diff options
author | Jakob Kaivo <jkk@ung.org> | 2024-01-10 19:47:34 -0500 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2024-01-10 19:47:34 -0500 |
commit | 37550072d57ca284a1ea8a7dbfde7b2f24760f47 (patch) | |
tree | 21e14512b22d8d0e6995334ece023954777063cd /src/signal/signal.c | |
parent | 7ecc2d92a45cbd7b7c13c80f51a1eaaaa3d8f286 (diff) |
insert common signal handler to support detecting standard library calls from within signal handlers
Diffstat (limited to 'src/signal/signal.c')
-rw-r--r-- | src/signal/signal.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/signal/signal.c b/src/signal/signal.c index 7faf7311..03913053 100644 --- a/src/signal/signal.c +++ b/src/signal/signal.c @@ -1,8 +1,24 @@ +#include <errno.h> #include "_signal.h" #include "_safety.h" +#include "_syscall.h" /** set a signal handler **/ +/* TODO: remove this very Linux-specific crap */ + typedef struct __siginfo siginfo_t; + struct linux_sigaction { + void (*sa_handler)(int); + int sa_flags; + void (*sa_restorer)(void); + unsigned char sa_mask[8]; + }; +#define sigaction(_sig, _act, _oact, _size) __scall4(sigaction, _sig, _act, _oact, _size) +#define SA_RESTART 0x10000000 +#define SA_RESTORER 0x04000000 +#undef SIG_DFL +#define SIG_DFL ((void (*)(int)) 0) + void (*signal(int sig, void (*func)(int)))(int) { if (__signal.current != 0 && __signal.current != sig) { @@ -19,6 +35,17 @@ void (*signal(int sig, void (*func)(int)))(int) void (*prev)(int) = __signal.handlers[sig]; __signal.handlers[sig] = func; + + struct linux_sigaction act = { 0 }; + act.sa_handler = __signal_handler; + act.sa_flags = SA_RESTART | SA_RESTORER; + + int ret = sigaction(sig, &act, NULL, 8); + if (ret != 0) { + errno = -ret; + return SIG_ERR; + } + return prev; } |