2016-11-13 19:05:30 +01:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/stat.h>
|
2016-11-20 23:04:31 +01:00
|
|
|
#include <unistd.h>
|
2016-11-13 19:05:30 +01:00
|
|
|
|
|
|
|
#include "components/ipc.hpp"
|
|
|
|
#include "config.hpp"
|
|
|
|
#include "utils/file.hpp"
|
|
|
|
#include "utils/io.hpp"
|
|
|
|
#include "utils/string.hpp"
|
|
|
|
|
2016-11-19 06:22:44 +01:00
|
|
|
POLYBAR_NS
|
2016-11-13 19:05:30 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Interrupt the blocked listener and
|
|
|
|
* remove the file handler
|
|
|
|
*/
|
|
|
|
ipc::~ipc() {
|
|
|
|
m_running = false;
|
|
|
|
|
|
|
|
if (!m_fifo.empty()) {
|
|
|
|
m_log.info("Interrupting ipc message receiver");
|
|
|
|
|
2016-11-20 23:29:42 +01:00
|
|
|
auto f = make_unique<file_util::file_ptr>(m_fifo);
|
2016-11-13 19:05:30 +01:00
|
|
|
char p[1]{'q'};
|
|
|
|
|
|
|
|
fwrite(p, sizeof(char), sizeof(p), (*f)());
|
|
|
|
unlink(m_fifo.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-14 09:21:18 +01:00
|
|
|
/**
|
|
|
|
* Register listener callback for ipc_command messages
|
|
|
|
*/
|
|
|
|
void ipc::attach_callback(callback<const ipc_command&>&& cb) {
|
|
|
|
m_command_callbacks.emplace_back(cb);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Register listener callback for ipc_hook messages
|
|
|
|
*/
|
|
|
|
void ipc::attach_callback(callback<const ipc_hook&>&& cb) {
|
|
|
|
m_hook_callbacks.emplace_back(cb);
|
|
|
|
}
|
|
|
|
|
2016-11-18 18:37:52 +01:00
|
|
|
/**
|
|
|
|
* Register listener callback for ipc_action messages
|
|
|
|
*/
|
|
|
|
void ipc::attach_callback(callback<const ipc_action&>&& cb) {
|
|
|
|
m_action_callbacks.emplace_back(cb);
|
|
|
|
}
|
|
|
|
|
2016-11-13 19:05:30 +01:00
|
|
|
/**
|
|
|
|
* Start listening for event messages
|
|
|
|
*/
|
|
|
|
void ipc::receive_messages() {
|
|
|
|
m_running = true;
|
|
|
|
m_fifo = string_util::replace(PATH_MESSAGING_FIFO, "%pid%", to_string(getpid()));
|
|
|
|
|
|
|
|
if (mkfifo(m_fifo.c_str(), 0666) == -1) {
|
|
|
|
m_log.err("Failed to create messaging channel");
|
|
|
|
}
|
|
|
|
|
|
|
|
m_log.info("Listening for ipc messages on: %s", m_fifo);
|
|
|
|
|
|
|
|
while ((m_fd = open(m_fifo.c_str(), O_RDONLY)) != -1 && m_running) {
|
|
|
|
parse(io_util::readline(m_fd));
|
|
|
|
close(m_fd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Process received message and delegate
|
|
|
|
* valid events to the target modules
|
|
|
|
*/
|
2016-11-14 09:21:18 +01:00
|
|
|
void ipc::parse(const string& payload) const {
|
2016-11-13 19:05:30 +01:00
|
|
|
if (payload.empty()) {
|
|
|
|
return;
|
2016-11-14 09:21:18 +01:00
|
|
|
} else if (payload.find(ipc_command::prefix) == 0) {
|
|
|
|
delegate(ipc_command{payload});
|
|
|
|
} else if (payload.find(ipc_hook::prefix) == 0) {
|
|
|
|
delegate(ipc_hook{payload});
|
2016-11-18 18:37:52 +01:00
|
|
|
} else if (payload.find(ipc_action::prefix) == 0) {
|
|
|
|
delegate(ipc_action{payload});
|
2016-11-13 19:05:30 +01:00
|
|
|
} else {
|
2016-11-14 09:21:18 +01:00
|
|
|
m_log.warn("Received unknown ipc message: (payload=%s)", payload);
|
2016-11-13 19:05:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-14 09:21:18 +01:00
|
|
|
/**
|
|
|
|
* Send ipc message to attached listeners
|
|
|
|
*/
|
|
|
|
void ipc::delegate(const ipc_command& message) const {
|
2016-11-25 13:55:15 +01:00
|
|
|
if (!m_command_callbacks.empty()) {
|
|
|
|
for (auto&& callback : m_command_callbacks) {
|
|
|
|
callback(message);
|
|
|
|
}
|
|
|
|
} else {
|
2016-11-14 09:21:18 +01:00
|
|
|
m_log.warn("Unhandled message (payload=%s)", message.payload);
|
2016-11-25 13:55:15 +01:00
|
|
|
}
|
2016-11-14 09:21:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send ipc message to attached listeners
|
|
|
|
*/
|
|
|
|
void ipc::delegate(const ipc_hook& message) const {
|
2016-11-25 13:55:15 +01:00
|
|
|
if (!m_hook_callbacks.empty()) {
|
|
|
|
for (auto&& callback : m_hook_callbacks) {
|
|
|
|
callback(message);
|
|
|
|
}
|
|
|
|
} else {
|
2016-11-14 09:21:18 +01:00
|
|
|
m_log.warn("Unhandled message (payload=%s)", message.payload);
|
2016-11-25 13:55:15 +01:00
|
|
|
}
|
2016-11-14 09:21:18 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 18:37:52 +01:00
|
|
|
/**
|
|
|
|
* Send ipc message to attached listeners
|
|
|
|
*/
|
|
|
|
void ipc::delegate(const ipc_action& message) const {
|
2016-11-25 13:55:15 +01:00
|
|
|
if (!m_action_callbacks.empty()) {
|
|
|
|
for (auto&& callback : m_action_callbacks) {
|
|
|
|
callback(message);
|
|
|
|
}
|
|
|
|
} else {
|
2016-11-18 18:37:52 +01:00
|
|
|
m_log.warn("Unhandled message (payload=%s)", message.payload);
|
2016-11-25 13:55:15 +01:00
|
|
|
}
|
2016-11-18 18:37:52 +01:00
|
|
|
}
|
|
|
|
|
2016-11-19 06:22:44 +01:00
|
|
|
POLYBAR_NS_END
|