scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

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:
Ainclude/bits/linux/amd64/arch/sigaction.h | 10++++++++++
Minclude/bits/linux/sys.h | 6+-----
Msrc/libc/arch/amd64/linux/.gitignore | 3++-
Msrc/libc/arch/amd64/linux/Makefile | 3++-
Msrc/libc/arch/amd64/linux/syscall.lst | 3++-
Msrc/libc/arch/arm/linux/syscall.lst | 2+-
Msrc/libc/arch/arm64/linux/syscall.lst | 2+-
Msrc/libc/arch/i386/linux/syscall.lst | 4++--
Msrc/libc/arch/linux/Makefile | 1+
Asrc/libc/arch/linux/_sigaction.c | 36++++++++++++++++++++++++++++++++++++
Msrc/libc/arch/posix/signal.c | 2++
Msrc/libc/objs/amd64-linux.mk | 4+++-
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\