npm

Nihal's Password Manager (WIP)
git clone git://git.nihaljere.xyz/npm
Log | Files | Refs | README | LICENSE

commit f05de96679402d87a2c527fa7a1d776bb0599d67
parent fa50fe10e7d68e1be6decd1eb9724330f4c740a9
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Tue, 12 Oct 2021 13:36:24 -0500

npm-agent: use setitimer instead of timerfd

setitimer + self-pipe is more portable. Since this interrupts the poll,
we also now check errno to see if poll failed due to an interrupt. If
it did, then we just restart the loop and continue as normal.
Consequently, the running boolean actually does something now, instead
of npm-agent stopping simply because poll failed.

Diffstat:
Mnpm-agent.c | 40++++++++++++++++++++++++++++++----------
1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/npm-agent.c b/npm-agent.c @@ -16,7 +16,7 @@ #include <stdlib.h> #include <string.h> #include <sys/socket.h> -#include <sys/timerfd.h> +#include <sys/time.h> #include <sys/un.h> #include <sys/wait.h> #include <unistd.h> @@ -44,6 +44,7 @@ ssize_t masterlen; char *inptr = inbuf; size_t inlen; struct pollfd fds[3]; +int timerpipe[2]; int xwrite(int fd, char *buf, size_t count) @@ -181,7 +182,7 @@ run_core() return status; } -const struct itimerspec timerspec = { +struct itimerval timerspec = { .it_interval = {0}, .it_value = { TIMEOUT/1000, (TIMEOUT % 1000) * 1000 * 1000 }, }; @@ -195,7 +196,7 @@ agent() if (get_master() != 0) return; - if (timerfd_settime(fds[TIMER].fd, 0, &timerspec, NULL) == -1) { + if (setitimer(ITIMER_REAL, &timerspec, NULL) == -1) { perror("failed to set cache timeout"); clear_master(); return; @@ -215,6 +216,18 @@ handler() running = false; } +void +alarm_handler() +{ + int ret; + while (ret = write(timerpipe[1], "a", 1) < 1) { + if (ret == -1) { + perror("failed to write to timerpipe"); + break; + } + } +} + int main() { @@ -224,12 +237,17 @@ main() }; int ret; - struct sigaction sa = { + struct sigaction sa_term = { .sa_handler = handler, }; - sigaction(SIGINT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); + struct sigaction sa_alarm = { + .sa_handler = alarm_handler, + }; + + sigaction(SIGINT, &sa_term, NULL); + sigaction(SIGTERM, &sa_term, NULL); + sigaction(SIGALRM, &sa_alarm, NULL); int sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock == -1) { @@ -247,20 +265,22 @@ main() goto error; } - int timer = timerfd_create(CLOCK_MONOTONIC, 0); - if (!timer) { - perror("failed to create timerfd"); + if (pipe(timerpipe) == -1) { + perror("failed to create timer pipe"); goto error; } fds[LISTENER].fd = sock; fds[LISTENER].events = POLLIN; - fds[TIMER].fd = timer; + fds[TIMER].fd = timerpipe[0]; fds[TIMER].events = POLLIN; fds[CLIENT].fd = -1; while (running) { if (poll(fds, sizeof(fds) / sizeof(fds[0]), -1) == -1) { + if (errno == EINTR) + continue; + perror("poll failed"); goto error; }