mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 22:28:24 +02:00
Make the full signal info available in our signal handler
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "loop-utils.h"
|
||||
#include "safe-wrappers.h"
|
||||
#include <signal.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "data-types.h"
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef __has_include
|
||||
#if __has_include(<sys/signalfd.h>)
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user