diff options
-rw-r--r-- | src/signal/__signal_handler.c | 2 | ||||
-rw-r--r-- | src/signal/_signal.h | 9 | ||||
-rw-r--r-- | src/signal/raise.c | 9 | ||||
-rw-r--r-- | src/signal/signal.c | 27 |
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; } |