From f29039db29a04212f152032965edb2e2cbaf5e02 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 5 Jun 2022 07:22:38 +0530 Subject: [PATCH] Make the full signal info available in our signal handler --- kitty/child-monitor.c | 6 +++--- kitty/loop-utils.c | 50 +++++++++++++++++++++++++++---------------- kitty/loop-utils.h | 3 ++- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index caad740f1..918897825 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -1242,9 +1242,9 @@ read_bytes(int fd, Screen *screen) { typedef struct { bool kill_signal, child_died, reload_config; } SignalSet; static void -handle_signal(int32_t signum, int32_t sigval, void *data) { +handle_signal(const siginfo_t *siginfo, void *data) { SignalSet *ss = data; - switch(signum) { + switch(siginfo->si_signo) { case SIGINT: case SIGTERM: ss->kill_signal = true; @@ -1256,7 +1256,7 @@ handle_signal(int32_t signum, int32_t sigval, void *data) { ss->reload_config = true; break; case SIGUSR2: - log_error("Received SIGUSR2: %d\n", sigval); + log_error("Received SIGUSR2: %d\n", siginfo->si_value.sival_int); break; default: break; diff --git a/kitty/loop-utils.c b/kitty/loop-utils.c index fd9fabdf1..7d6ae2bd5 100644 --- a/kitty/loop-utils.c +++ b/kitty/loop-utils.c @@ -7,7 +7,6 @@ #include "loop-utils.h" #include "safe-wrappers.h" -#include bool init_loop_data(LoopData *ld) { @@ -29,16 +28,20 @@ init_loop_data(LoopData *ld) { static int signal_write_fd = -1; static void -handle_signal(int sig_num, siginfo_t *si, void *ucontext UNUSED) { +handle_signal(int sig_num UNUSED, siginfo_t *si, void *ucontext UNUSED) { int save_err = errno; - char buf[8]; - int32_t sigval = si->si_value.sival_int, signum = sig_num; - memcpy(buf, &signum, 4); - memcpy(buf + 4, &sigval, 4); - while (signal_write_fd != -1) { - ssize_t ret = write(signal_write_fd, buf, 8); - if (ret < 0 && errno == EINTR) continue; - break; + char *buf = (char*)si; + size_t sz = sizeof(siginfo_t); + while (signal_write_fd != -1 && sz) { + // as long as sz is less than PIPE_BUF write will either write all or return -1 with EAGAIN + // so we are guaranteed atomic writes + ssize_t ret = write(signal_write_fd, buf, sz); + if (ret <= 0) { + if (errno == EINTR) continue; + break; + } + sz -= ret; + buf += ret; } errno = save_err; } @@ -109,8 +112,8 @@ install_signal_handlers(LoopData *ld) { #else if (!self_pipe(ld->signal_fds, true)) return false; signal_write_fd = ld->signal_fds[1]; - struct sigaction act = {.sa_sigaction=handle_signal, .sa_flags=SA_SIGINFO}; -#define SA(which) { if (sigaction(which, &act, NULL) != 0) return false; if (siginterrupt(which, false) != 0) return false; } + struct sigaction act = {.sa_sigaction=handle_signal, .sa_flags=SA_SIGINFO | SA_RESTART}; +#define SA(which) { if (sigaction(which, &act, NULL) != 0) return false; } SA(SIGINT); SA(SIGTERM); SA(SIGCHLD); SA(SIGUSR1); SA(SIGUSR2); #undef SA ld->signal_read_fd = ld->signal_fds[0]; @@ -123,6 +126,7 @@ void read_signals(int fd, handle_signal_func callback, void *data) { #ifdef HAS_SIGNAL_FD static struct signalfd_siginfo fdsi[32]; + siginfo_t si; while (true) { ssize_t s = read(fd, &fdsi, sizeof(fdsi)); if (s < 0) { @@ -137,10 +141,19 @@ read_signals(int fd, handle_signal_func callback, void *data) { log_error("Incomplete signal read from signalfd"); break; } - for (size_t i = 0; i < num_signals; i++) callback(fdsi[i].ssi_signo, fdsi[i].ssi_int, data); + for (size_t i = 0; i < num_signals; i++) { + si.si_signo = fdsi[i].ssi_signo; + si.si_code = fdsi[i].ssi_code; + si.si_pid = fdsi[i].ssi_pid; + si.si_uid = fdsi[i].ssi_uid; + si.si_addr = (void*)fdsi[i].ssi_addr; + si.si_status = fdsi[i].ssi_status; + si.si_value.sival_int = fdsi[i].ssi_int; + callback(&si, data); + } } #else - static char buf[256]; + static char buf[sizeof(siginfo_t) * 8]; static size_t buf_pos = 0; while(true) { ssize_t len = read(fd, buf + buf_pos, sizeof(buf) - buf_pos); @@ -150,11 +163,10 @@ read_signals(int fd, handle_signal_func callback, void *data) { break; } buf_pos += len; - while (buf_pos >= 8) { - int32_t *sdata = (int32_t*)buf; - callback(sdata[0], sdata[1], data); - memmove(buf, buf + 8, 8); - buf_pos -= 8; + while (buf_pos >= sizeof(siginfo_t)) { + callback((siginfo_t*)buf, data); + memmove(buf, buf + sizeof(siginfo_t), sizeof(siginfo_t)); + buf_pos -= sizeof(siginfo_t); } if (len == 0) break; } diff --git a/kitty/loop-utils.h b/kitty/loop-utils.h index dcbfdbd68..9139e1862 100644 --- a/kitty/loop-utils.h +++ b/kitty/loop-utils.h @@ -9,6 +9,7 @@ #include "data-types.h" #include #include +#include #ifdef __has_include #if __has_include() @@ -37,7 +38,7 @@ typedef struct { int wakeup_read_fd; int signal_read_fd; } LoopData; -typedef void(*handle_signal_func)(int32_t, int32_t, void *data); +typedef void(*handle_signal_func)(const siginfo_t* siginfo, void *data); bool init_loop_data(LoopData *ld); void free_loop_data(LoopData *ld);