mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-27 18:51:41 +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;
|
typedef struct { bool kill_signal, child_died, reload_config; } SignalSet;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_signal(int32_t signum, int32_t sigval, void *data) {
|
handle_signal(const siginfo_t *siginfo, void *data) {
|
||||||
SignalSet *ss = data;
|
SignalSet *ss = data;
|
||||||
switch(signum) {
|
switch(siginfo->si_signo) {
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
ss->kill_signal = true;
|
ss->kill_signal = true;
|
||||||
@@ -1256,7 +1256,7 @@ handle_signal(int32_t signum, int32_t sigval, void *data) {
|
|||||||
ss->reload_config = true;
|
ss->reload_config = true;
|
||||||
break;
|
break;
|
||||||
case SIGUSR2:
|
case SIGUSR2:
|
||||||
log_error("Received SIGUSR2: %d\n", sigval);
|
log_error("Received SIGUSR2: %d\n", siginfo->si_value.sival_int);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#include "loop-utils.h"
|
#include "loop-utils.h"
|
||||||
#include "safe-wrappers.h"
|
#include "safe-wrappers.h"
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
init_loop_data(LoopData *ld) {
|
init_loop_data(LoopData *ld) {
|
||||||
@@ -29,16 +28,20 @@ init_loop_data(LoopData *ld) {
|
|||||||
static int signal_write_fd = -1;
|
static int signal_write_fd = -1;
|
||||||
|
|
||||||
static void
|
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;
|
int save_err = errno;
|
||||||
char buf[8];
|
char *buf = (char*)si;
|
||||||
int32_t sigval = si->si_value.sival_int, signum = sig_num;
|
size_t sz = sizeof(siginfo_t);
|
||||||
memcpy(buf, &signum, 4);
|
while (signal_write_fd != -1 && sz) {
|
||||||
memcpy(buf + 4, &sigval, 4);
|
// as long as sz is less than PIPE_BUF write will either write all or return -1 with EAGAIN
|
||||||
while (signal_write_fd != -1) {
|
// so we are guaranteed atomic writes
|
||||||
ssize_t ret = write(signal_write_fd, buf, 8);
|
ssize_t ret = write(signal_write_fd, buf, sz);
|
||||||
if (ret < 0 && errno == EINTR) continue;
|
if (ret <= 0) {
|
||||||
break;
|
if (errno == EINTR) continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sz -= ret;
|
||||||
|
buf += ret;
|
||||||
}
|
}
|
||||||
errno = save_err;
|
errno = save_err;
|
||||||
}
|
}
|
||||||
@@ -109,8 +112,8 @@ install_signal_handlers(LoopData *ld) {
|
|||||||
#else
|
#else
|
||||||
if (!self_pipe(ld->signal_fds, true)) return false;
|
if (!self_pipe(ld->signal_fds, true)) return false;
|
||||||
signal_write_fd = ld->signal_fds[1];
|
signal_write_fd = ld->signal_fds[1];
|
||||||
struct sigaction act = {.sa_sigaction=handle_signal, .sa_flags=SA_SIGINFO};
|
struct sigaction act = {.sa_sigaction=handle_signal, .sa_flags=SA_SIGINFO | SA_RESTART};
|
||||||
#define SA(which) { if (sigaction(which, &act, NULL) != 0) return false; if (siginterrupt(which, false) != 0) return false; }
|
#define SA(which) { if (sigaction(which, &act, NULL) != 0) return false; }
|
||||||
SA(SIGINT); SA(SIGTERM); SA(SIGCHLD); SA(SIGUSR1); SA(SIGUSR2);
|
SA(SIGINT); SA(SIGTERM); SA(SIGCHLD); SA(SIGUSR1); SA(SIGUSR2);
|
||||||
#undef SA
|
#undef SA
|
||||||
ld->signal_read_fd = ld->signal_fds[0];
|
ld->signal_read_fd = ld->signal_fds[0];
|
||||||
@@ -123,6 +126,7 @@ void
|
|||||||
read_signals(int fd, handle_signal_func callback, void *data) {
|
read_signals(int fd, handle_signal_func callback, void *data) {
|
||||||
#ifdef HAS_SIGNAL_FD
|
#ifdef HAS_SIGNAL_FD
|
||||||
static struct signalfd_siginfo fdsi[32];
|
static struct signalfd_siginfo fdsi[32];
|
||||||
|
siginfo_t si;
|
||||||
while (true) {
|
while (true) {
|
||||||
ssize_t s = read(fd, &fdsi, sizeof(fdsi));
|
ssize_t s = read(fd, &fdsi, sizeof(fdsi));
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
@@ -137,10 +141,19 @@ read_signals(int fd, handle_signal_func callback, void *data) {
|
|||||||
log_error("Incomplete signal read from signalfd");
|
log_error("Incomplete signal read from signalfd");
|
||||||
break;
|
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
|
#else
|
||||||
static char buf[256];
|
static char buf[sizeof(siginfo_t) * 8];
|
||||||
static size_t buf_pos = 0;
|
static size_t buf_pos = 0;
|
||||||
while(true) {
|
while(true) {
|
||||||
ssize_t len = read(fd, buf + buf_pos, sizeof(buf) - buf_pos);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
buf_pos += len;
|
buf_pos += len;
|
||||||
while (buf_pos >= 8) {
|
while (buf_pos >= sizeof(siginfo_t)) {
|
||||||
int32_t *sdata = (int32_t*)buf;
|
callback((siginfo_t*)buf, data);
|
||||||
callback(sdata[0], sdata[1], data);
|
memmove(buf, buf + sizeof(siginfo_t), sizeof(siginfo_t));
|
||||||
memmove(buf, buf + 8, 8);
|
buf_pos -= sizeof(siginfo_t);
|
||||||
buf_pos -= 8;
|
|
||||||
}
|
}
|
||||||
if (len == 0) break;
|
if (len == 0) break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "data-types.h"
|
#include "data-types.h"
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#ifdef __has_include
|
#ifdef __has_include
|
||||||
#if __has_include(<sys/signalfd.h>)
|
#if __has_include(<sys/signalfd.h>)
|
||||||
@@ -37,7 +38,7 @@ typedef struct {
|
|||||||
int wakeup_read_fd;
|
int wakeup_read_fd;
|
||||||
int signal_read_fd;
|
int signal_read_fd;
|
||||||
} LoopData;
|
} 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);
|
bool init_loop_data(LoopData *ld);
|
||||||
void free_loop_data(LoopData *ld);
|
void free_loop_data(LoopData *ld);
|
||||||
|
|||||||
Reference in New Issue
Block a user