refactor(IPC): use sigc signal

This commit is contained in:
Alex
2019-04-19 11:09:06 +02:00
parent 4c8f4f82dc
commit bb1cf7570e
9 changed files with 140 additions and 91 deletions

View File

@ -1,21 +1,29 @@
#include "modules/sway/ipc/client.hpp"
#include <fcntl.h>
waybar::modules::sway::Ipc::Ipc() {
namespace waybar::modules::sway {
Ipc::Ipc() {
const std::string& socketPath = getSocketPath();
fd_ = open(socketPath);
fd_event_ = open(socketPath);
}
waybar::modules::sway::Ipc::~Ipc() {
Ipc::~Ipc() {
// To fail the IPC header
write(fd_, "close-sway-ipc", 14);
write(fd_event_, "close-sway-ipc", 14);
close(fd_);
close(fd_event_);
if (fd_ > 0) {
close(fd_);
fd_ = -1;
}
if (fd_event_ > 0) {
close(fd_event_);
fd_event_ = -1;
}
}
const std::string waybar::modules::sway::Ipc::getSocketPath() const {
const std::string Ipc::getSocketPath() const {
const char* env = getenv("SWAYSOCK");
if (env != nullptr) {
return std::string(env);
@ -33,6 +41,9 @@ const std::string waybar::modules::sway::Ipc::getSocketPath() const {
}
pclose(in);
str = str_buf;
if (str.empty()) {
throw std::runtime_error("Socket path is empty");
}
}
if (str.back() == '\n') {
str.pop_back();
@ -40,12 +51,14 @@ const std::string waybar::modules::sway::Ipc::getSocketPath() const {
return str;
}
int waybar::modules::sway::Ipc::open(const std::string& socketPath) const {
struct sockaddr_un addr = {0};
int fd = -1;
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
int Ipc::open(const std::string& socketPath) const {
int32_t fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1) {
throw std::runtime_error("Unable to open Unix socket");
}
(void)fcntl(fd, F_SETFD, FD_CLOEXEC);
struct sockaddr_un addr;
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1);
addr.sun_path[sizeof(addr.sun_path) - 1] = 0;
@ -56,7 +69,7 @@ int waybar::modules::sway::Ipc::open(const std::string& socketPath) const {
return fd;
}
struct waybar::modules::sway::Ipc::ipc_response waybar::modules::sway::Ipc::recv(int fd) const {
struct Ipc::ipc_response Ipc::recv(int fd) const {
std::string header;
header.resize(ipc_header_size_);
auto data32 = reinterpret_cast<uint32_t*>(header.data() + ipc_magic_.size());
@ -65,6 +78,10 @@ struct waybar::modules::sway::Ipc::ipc_response waybar::modules::sway::Ipc::recv
while (total < ipc_header_size_) {
auto res = ::recv(fd, header.data() + total, ipc_header_size_ - total, 0);
if (res <= 0) {
if (res <= 0 && (fd_event_ == -1 || fd_ == -1)) {
// IPC is closed so just return empty response
return {0, 0, ""};
}
throw std::runtime_error("Unable to receive IPC header");
}
total += res;
@ -88,8 +105,7 @@ struct waybar::modules::sway::Ipc::ipc_response waybar::modules::sway::Ipc::recv
return {data32[0], data32[1], &payload.front()};
}
struct waybar::modules::sway::Ipc::ipc_response waybar::modules::sway::Ipc::send(
int fd, uint32_t type, const std::string& payload) const {
struct Ipc::ipc_response Ipc::send(int fd, uint32_t type, const std::string& payload) const {
std::string header;
header.resize(ipc_header_size_);
auto data32 = reinterpret_cast<uint32_t*>(header.data() + ipc_magic_.size());
@ -103,21 +119,24 @@ struct waybar::modules::sway::Ipc::ipc_response waybar::modules::sway::Ipc::send
if (::send(fd, payload.c_str(), payload.size(), 0) == -1) {
throw std::runtime_error("Unable to send IPC payload");
}
return recv(fd);
return Ipc::recv(fd);
}
struct waybar::modules::sway::Ipc::ipc_response waybar::modules::sway::Ipc::sendCmd(
uint32_t type, const std::string& payload) const {
return send(fd_, type, payload);
void Ipc::sendCmd(uint32_t type, const std::string& payload) const {
const auto res = Ipc::send(fd_, type, payload);
signal_cmd.emit(res);
}
void waybar::modules::sway::Ipc::subscribe(const std::string& payload) const {
auto res = send(fd_event_, IPC_SUBSCRIBE, payload);
void Ipc::subscribe(const std::string& payload) const {
auto res = Ipc::send(fd_event_, IPC_SUBSCRIBE, payload);
if (res.payload != "{\"success\": true}") {
throw std::runtime_error("Unable to subscribe ipc event");
}
}
struct waybar::modules::sway::Ipc::ipc_response waybar::modules::sway::Ipc::handleEvent() const {
return recv(fd_event_);
void Ipc::handleEvent() const {
const auto res = Ipc::recv(fd_event_);
signal_event.emit(res);
}
} // namespace waybar::modules::sway