summaryrefslogtreecommitdiff
path: root/src/signal/signal.c
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2024-01-10 19:47:34 -0500
committerJakob Kaivo <jkk@ung.org>2024-01-10 19:47:34 -0500
commit37550072d57ca284a1ea8a7dbfde7b2f24760f47 (patch)
tree21e14512b22d8d0e6995334ece023954777063cd /src/signal/signal.c
parent7ecc2d92a45cbd7b7c13c80f51a1eaaaa3d8f286 (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.c27
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;
}