polybar/src/components/ipc.cpp

91 lines
2.2 KiB
C++
Raw Normal View History

2016-11-13 18:05:30 +00:00
#include <fcntl.h>
#include <sys/stat.h>
2016-11-20 22:04:31 +00:00
#include <unistd.h>
2016-11-13 18:05:30 +00:00
#include "components/ipc.hpp"
#include "config.hpp"
#include "events/signal.hpp"
#include "events/signal_emitter.hpp"
2016-12-09 08:02:47 +00:00
#include "utils/factory.hpp"
2016-11-13 18:05:30 +00:00
#include "utils/file.hpp"
#include "utils/io.hpp"
#include "utils/string.hpp"
2016-11-19 05:22:44 +00:00
POLYBAR_NS
2016-11-13 18:05:30 +00:00
2016-12-26 09:36:14 +00:00
namespace sig_ipc = signals::ipc;
2016-12-09 08:02:47 +00:00
/**
* Create instance
*/
2016-12-09 08:40:46 +00:00
ipc::make_type ipc::make() {
2016-12-09 08:02:47 +00:00
return factory_util::unique<ipc>(signal_emitter::make(), logger::make());
}
2016-11-13 18:05:30 +00:00
/**
* Construct ipc handler
2016-11-13 18:05:30 +00:00
*/
ipc::ipc(signal_emitter& emitter, const logger& logger) : m_sig(emitter), m_log(logger) {
m_path = string_util::replace(PATH_MESSAGING_FIFO, "%pid%", to_string(getpid()));
2016-11-13 18:05:30 +00:00
if (mkfifo(m_path.c_str(), 0666) == -1) {
throw system_error("Failed to create ipc channel");
}
2016-11-13 18:05:30 +00:00
m_log.info("Created ipc channel at: %s", m_path);
m_fd = file_util::make_file_descriptor(m_path, O_RDONLY | O_NONBLOCK);
}
2016-11-13 18:05:30 +00:00
/**
* Deconstruct ipc handler
*/
ipc::~ipc() {
2016-12-21 22:22:02 +00:00
m_fd.reset();
if (!m_path.empty()) {
m_log.trace("ipc: Removing file handle");
unlink(m_path.c_str());
2016-11-13 18:05:30 +00:00
}
}
/**
* Receive available ipc messages and delegate valid events
2016-11-13 18:05:30 +00:00
*/
void ipc::receive_message() {
m_log.info("Receiving ipc message");
2016-11-13 18:05:30 +00:00
char buffer[BUFSIZ]{'\0'};
ssize_t bytes_read{0};
2016-11-13 18:05:30 +00:00
2016-12-21 22:22:02 +00:00
if ((bytes_read = read(*m_fd, &buffer, BUFSIZ)) == -1) {
m_log.err("Failed to read from ipc channel (err: %s)", strerror(errno));
2016-11-13 18:05:30 +00:00
}
if (!bytes_read) {
2016-11-13 18:05:30 +00:00
return;
}
string payload{string_util::trim(string{buffer}, '\n')};
if (payload.find(ipc_command::prefix) == 0) {
2016-12-26 09:36:14 +00:00
m_sig.emit(sig_ipc::command{payload.substr(strlen(ipc_command::prefix))});
} else if (payload.find(ipc_hook::prefix) == 0) {
2016-12-26 09:36:14 +00:00
m_sig.emit(sig_ipc::hook{payload.substr(strlen(ipc_hook::prefix))});
} else if (payload.find(ipc_action::prefix) == 0) {
2016-12-26 09:36:14 +00:00
m_sig.emit(sig_ipc::action{payload.substr(strlen(ipc_action::prefix))});
} else if (!payload.empty()) {
m_log.warn("Received unknown ipc message: (payload=%s)", payload);
2016-11-13 18:05:30 +00:00
}
m_fd = file_util::make_file_descriptor(m_path, O_RDONLY | O_NONBLOCK);
}
/**
* Get the file descriptor to the ipc channel
*/
int ipc::get_file_descriptor() const {
2016-12-21 22:22:02 +00:00
return *m_fd;
2016-11-13 18:05:30 +00:00
}
2016-11-19 05:22:44 +00:00
POLYBAR_NS_END