From a46a8824924c9264b876dbed3c6a8163f6ac1012 Mon Sep 17 00:00:00 2001 From: Gustav Behm Date: Fri, 29 Mar 2024 07:05:56 +0100 Subject: [PATCH] Receive triggers --- c-impl/action.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/c-impl/action.c b/c-impl/action.c index 1d002ea..239de2c 100644 --- a/c-impl/action.c +++ b/c-impl/action.c @@ -1,8 +1,12 @@ +#define _GNU_SOURCE + #include #include #include #include #include +#include +#include #define LIBR_IMPLEMENTATION #include "r.h" @@ -147,6 +151,25 @@ const char* iso8601_timespec(const struct timespec* ts) return buf; } +static void prepare_socket_path(const char* sp) +{ + struct stat st; + int r = stat(sp, &st); + if(r == 0) { + if((st.st_mode & S_IFMT) == S_IFSOCK) { + debug("socket already exists, trying to unlink: %s", sp); + r = unlink(sp); + CHECK(r, "unlink(%s)", sp); + } else { + failwith("socket path already exists (and is not a socket): %s", sp); + } + } else if(r == -1 && errno != ENOENT) { + CHECK(r, "stat(%s)", sp); + } else { + xdg_makedirs(dirname(strdupa(sp))); + } +} + int main(int argc, char* argv[]) { struct options o; @@ -197,6 +220,13 @@ int main(int argc, char* argv[]) return 0; } + prepare_socket_path(socket_path); + + int r = bind(fd, (const struct sockaddr*)&addr, sizeof(addr)); + CHECK(r, "bind(%s)", socket_path); + + set_blocking(fd, 0); + struct state st = { .running = 1, }; @@ -205,6 +235,7 @@ int main(int argc, char* argv[]) struct pollfd fds[] = { { .fd = signalfd_fd(&st), .events = POLLIN }, + { .fd = fd, .events = POLLIN }, }; while(st.running) { @@ -216,6 +247,23 @@ int main(int argc, char* argv[]) fds[0].revents &= ~POLLIN; } + if(fds[1].revents & POLLIN) { + struct msg msg; + ssize_t s = recvfrom(fd, &msg, sizeof(msg), 0, NULL, NULL); + CHECK(s, "recvfrom(%s)", socket_path); + + if(s != sizeof(msg)) { + failwith("unexpected partial recvfrom"); + } + + if(strncmp(msg.action, o.action, sizeof(msg.action)) == 0) { + info("triggered: %s (%s)", o.action, iso8601_timespec(&msg.timestamp)); + st.running = 0; + } + + fds[1].revents &= ~POLLIN; + } + for(size_t i = 0; i < LENGTH(fds); i++) { if(fds[i].revents != 0) { failwith("unhandled poll events: " @@ -228,6 +276,10 @@ int main(int argc, char* argv[]) debug("graceful shutdown"); signalfd_deinit(&st); + r = close(fd); CHECK(r, "close"); + r = unlink(socket_path); + CHECK(r, "unlink(%s)", socket_path); + exit: xdg_free(xdg); -- 2.45.2