summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/signal/__signal_handler.c2
-rw-r--r--src/signal/_signal.h9
-rw-r--r--src/signal/raise.c9
-rw-r--r--src/signal/signal.c27
4 files changed, 40 insertions, 7 deletions
diff --git a/src/signal/__signal_handler.c b/src/signal/__signal_handler.c
index 102ed774..fc0cc45f 100644
--- a/src/signal/__signal_handler.c
+++ b/src/signal/__signal_handler.c
@@ -1,6 +1,8 @@
#include <stddef.h>
#include "_signal.h"
+#include <stdio.h>
+
void __signal_handler(int sig)
{
__signal.current = sig;
diff --git a/src/signal/_signal.h b/src/signal/_signal.h
index d699834c..f29a21d2 100644
--- a/src/signal/_signal.h
+++ b/src/signal/_signal.h
@@ -1,8 +1,17 @@
#ifndef SIGNAL__SIGNAL_H
#define SIGNAL__SIGNAL_H
+#include <signal.h>
+
+#define NSIGNALS 256
+
+typedef void (*handler)(int);
+
extern struct __signal {
int current;
+ handler handlers[NSIGNALS];
} __signal;
+void __signal_handler(int);
+
#endif
diff --git a/src/signal/raise.c b/src/signal/raise.c
index f7db89b3..56bf3209 100644
--- a/src/signal/raise.c
+++ b/src/signal/raise.c
@@ -1,13 +1,11 @@
-#if 0
-
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
#define POSIX_FORCED
#endif
-#include <sys/types.h>
+//#include <sys/types.h>
#include <signal.h>
-#include <unistd.h>
+//#include <unistd.h>
#ifdef POSIX_FORCED
#include "_syscall.h"
@@ -37,6 +35,3 @@ sends the signal ARGUMENT(sig) to the current program.
/*
STDC(1)
*/
-
-
-#endif
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;
}