commit d23376cb646303034a20b4f442c9320e4ebe4f1d
parent 5fb4a0688927828adc8a459dc9cf4fdd20b78ffb
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 1 Oct 2021 21:27:43 +0200
libc/linux: Add _sigaction() wrapper
Linux sigaction() syscall does not have the same prototype
than the POSIX version. For this reason is needed a wrapper
to that is able to adapt the interface and set the expected
behaviour of signal() in linux systems.
Diffstat:
12 files changed, 63 insertions(+), 13 deletions(-)
diff --git a/include/bits/linux/amd64/arch/sigaction.h b/include/bits/linux/amd64/arch/sigaction.h
@@ -0,0 +1,10 @@
+#define SA_RESTORER 0x04000000
+
+struct sigaction {
+ void (*sa_handler)(int);
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+ unsigned sa_mask[2];
+};
+
+extern int __sigaction(int, struct sigaction *, struct sigaction *, size_t);
diff --git a/include/bits/linux/sys.h b/include/bits/linux/sys.h
@@ -12,11 +12,7 @@
typedef int pid_t;
-struct sigaction {
- void (*sa_handler)(int);
- int sa_mask;
- int sa_flags;
-};
+struct sigaction;
extern pid_t _getpid(void);
extern int _kill(pid_t, int);
diff --git a/src/libc/arch/amd64/linux/.gitignore b/src/libc/arch/amd64/linux/.gitignore
@@ -1,3 +1,4 @@
+__sigaction.s
_close.s
_exit.s
_getpid.s
@@ -7,7 +8,7 @@ _kill.s
_lseek.s
_open.s
_read.s
-_sigaction.s
+_sigreturn.s
_sys_brk.s
_sys_errlist.c
_unlink.s
diff --git a/src/libc/arch/amd64/linux/Makefile b/src/libc/arch/amd64/linux/Makefile
@@ -6,6 +6,7 @@ include $(PROJECTDIR)/scripts/rules.mk
include ../../../rules.mk
GENOBJS =\
+ __sigaction.$O\
_close.$O\
_exit.$O\
_getpid.$O\
@@ -15,7 +16,7 @@ GENOBJS =\
_lseek.$O\
_open.$O\
_read.$O\
- _sigaction.$O\
+ _sigreturn.$O\
_sys_brk.$O\
_unlink.$O\
_write.$O\
diff --git a/src/libc/arch/amd64/linux/syscall.lst b/src/libc/arch/amd64/linux/syscall.lst
@@ -6,7 +6,8 @@
3 _close 1
8 _lseek 3
12 _sys_brk 1
-13 _sigaction 3
+13 __sigaction 4
+15 _sigreturn 0
39 _getpid 0
60 _exit 1
62 _kill 2
diff --git a/src/libc/arch/arm/linux/syscall.lst b/src/libc/arch/arm/linux/syscall.lst
@@ -8,4 +8,4 @@
37 _kill
19 _lseek
45 _sys_brk
-134 _sigaction
+134 __sigaction
diff --git a/src/libc/arch/arm64/linux/syscall.lst b/src/libc/arch/arm64/linux/syscall.lst
@@ -6,6 +6,6 @@
64 _write
93 _Exit
129 _kill
-134 _sigaction
+134 __sigaction
172 _getpid
214 _sys_brk
diff --git a/src/libc/arch/i386/linux/syscall.lst b/src/libc/arch/i386/linux/syscall.lst
@@ -7,5 +7,5 @@
19 _lseek 3
20 _getpid 0
37 _kill 2
-45 _sys_brk 1
-67 _sigaction 3
+45 _sys_brk 1
+67 __sigaction 4
diff --git a/src/libc/arch/linux/Makefile b/src/libc/arch/linux/Makefile
@@ -6,6 +6,7 @@ include ../../rules.mk
OBJS=\
_brk.$O\
_getheap.$O\
+ _sigaction.$O\
all: $(OBJS)
diff --git a/src/libc/arch/linux/_sigaction.c b/src/libc/arch/linux/_sigaction.c
@@ -0,0 +1,36 @@
+#include <string.h>
+
+#include <arch/sigaction.h>
+#include <sys.h>
+
+extern void _sigreturn(void);
+
+int _sigaction(int sig, struct sigaction *sa, struct sigaction *old)
+{
+ int r;
+ struct sigaction ksa, kold;
+
+ if (sa) {
+ ksa.sa_handler = sa->sa_handler;
+ ksa.sa_flags = sa->sa_flags | SA_RESTORER;
+ ksa.sa_restorer = _sigreturn;
+ memcpy(&ksa.sa_mask, &sa->sa_mask, sizeof(ksa.sa_mask));
+ }
+
+ r = __sigaction(sig,
+ sa ? &ksa : NULL,
+ old ? &kold : NULL,
+ sizeof(ksa.sa_mask));
+
+ if (r != 0)
+ return -1;
+
+
+ if (old) {
+ old->sa_handler = kold.sa_handler;
+ old->sa_flags = kold.sa_flags;
+ memcpy(&old->sa_mask, &kold.sa_mask, sizeof kold.sa_mask);
+ }
+
+ return 0;
+}
diff --git a/src/libc/arch/posix/signal.c b/src/libc/arch/posix/signal.c
@@ -1,5 +1,7 @@
#include <signal.h>
+#include <stddef.h>
+#include <arch/sigaction.h>
#include <sys.h>
#undef signal
diff --git a/src/libc/objs/amd64-linux.mk b/src/libc/objs/amd64-linux.mk
@@ -2,6 +2,7 @@ include objs/common-objs.mk
OBJS =\
$(COMMON_OBJS)\
+ arch/amd64/linux/__sigaction.$O\
arch/amd64/linux/_cerrno.$O\
arch/amd64/linux/_close.$O\
arch/amd64/linux/_exit.$O\
@@ -12,7 +13,7 @@ OBJS =\
arch/amd64/linux/_lseek.$O\
arch/amd64/linux/_open.$O\
arch/amd64/linux/_read.$O\
- arch/amd64/linux/_sigaction.$O\
+ arch/amd64/linux/_sigreturn.$O\
arch/amd64/linux/_sys_brk.$O\
arch/amd64/linux/_sys_errlist.$O\
arch/amd64/linux/_unlink.$O\
@@ -30,6 +31,7 @@ OBJS =\
arch/amd64/strcpy.$O\
arch/linux/_brk.$O\
arch/linux/_getheap.$O\
+ arch/linux/_sigaction.$O\
arch/posix/_getheap.$O\
arch/posix/_open.$O\
arch/posix/_systime.$O\