summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/signal/sigaction.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c
index addde011..c9fddd21 100644
--- a/src/signal/sigaction.c
+++ b/src/signal/sigaction.c
@@ -1,10 +1,47 @@
+#include "stddef.h"
#include "sys/types.h"
#include <signal.h>
+#include "_syscall.h"
int sigaction(int sig, const struct sigaction * restrict act, struct sigaction * restrict oact)
{
- (void)sig; (void)act; (void)oact;
- return 0;
+ struct linux_action {
+ union {
+ void (*handler)(int);
+ void (*action)(int, struct sigaction *, void *);
+ } fn;
+ unsigned long flags;
+ void (*restorer)(void);
+ sigset_t mask;
+ };
+
+ SYSCALL_NUMBER(scno, sigaction, -1);
+ struct linux_action a = { 0 }, o = { 0 };
+ int ret = -1;
+
+ a.fn.handler = act->sa_handler;
+ #ifdef SA_SIGINFO
+ if (act->sa_flags & SA_SIGINFO) {
+ a.fn.action = act->sa_sigaction;
+ #endif
+
+ a.flags = act->sa_flags;
+ a.mask = act->sa_mask;
+
+ ret = __syscall(scno, sig, &a, &o, sizeof(act->sa_mask), 0, 0);
+ if (ret != -1 && oact != NULL) {
+ oact->sa_handler = o.fn.handler;
+ #ifdef SA_SIGINFO
+ if (o.flags & SA_SIGINFO) {
+ oact->sa_sigaction = o.fn.action;
+ }
+ #endif
+
+ oact->sa_flags = o.flags;
+ oact->sa_mask = o.mask;
+ }
+
+ return ret;
}
/*