From 684052df5e68f1bbf610441b43d4f0542fe19fd1 Mon Sep 17 00:00:00 2001 From: Johannes Schlatow Date: Thu, 14 Dec 2017 16:03:55 +0100 Subject: [PATCH] base-linux: implement lx_sigmask/lx_sigword explicitly In newer glibc versions, the '__sigword' and '__sigmask' macros are only available in sigsetops.h which is not installed. These macros are not system-specific, hence we implement them explicitly ourselves. Fixes #2616 --- .../src/lib/syscall/linux_syscalls.h | 57 ++++++++++++------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/repos/base-linux/src/lib/syscall/linux_syscalls.h b/repos/base-linux/src/lib/syscall/linux_syscalls.h index 68e37eb180..1b9a091a2e 100644 --- a/repos/base-linux/src/lib/syscall/linux_syscalls.h +++ b/repos/base-linux/src/lib/syscall/linux_syscalls.h @@ -53,6 +53,7 @@ #include #include + #undef size_t @@ -227,6 +228,7 @@ enum { LX_SIGCHLD = 17, /* child process changed state, i.e., terminated */ LX_SIGCANCEL = 32, /* accoring to glibc, this equals SIGRTMIN, used for killing threads */ + LX_NSIG = 64, /* number of different signals supported */ }; @@ -280,7 +282,7 @@ inline int lx_sigaction(int signum, void (*handler)(int), bool altstack) lx_sigemptyset(&act.mask); - return lx_syscall(SYS_rt_sigaction, signum, &act, 0UL, _NSIG/8); + return lx_syscall(SYS_rt_sigaction, signum, &act, 0UL, LX_NSIG/8); } @@ -354,37 +356,54 @@ inline int lx_futex(const int *uaddr, int op, int val) */ class Lx_sigset { - unsigned long int _value[_SIGSET_NWORDS]; + private: + + enum { + BITS_PER_LONG = 8 * sizeof(unsigned long), + SIGSET_SIZE = LX_NSIG / BITS_PER_LONG + }; + + unsigned long _value[SIGSET_SIZE]; + + /* + * Both '__sigword' and '__sigmask' were macros defined in the glibc + * header file 'bits/sigset.h'. The macros were moved in later versions + * and, therefore, we implement them explicitly. + */ + + /* return mask that includes the bit for 'signum' only (was __sigmask) */ + unsigned long _mask(int signum) + { + return (1UL) << ((signum - 1) % BITS_PER_LONG); + } + + /* return word index for 'signum' (was __sigword) */ + unsigned _word(int signum) + { + return (signum - 1) / BITS_PER_LONG; + } public: /** * Constructor */ - Lx_sigset() { } + Lx_sigset() { Genode::memset(_value, 0, sizeof(_value)); } /** * Constructor * * \param signum set specified entry of sigset */ - Lx_sigset(int signum) + Lx_sigset(int signum) : Lx_sigset() { - - for (unsigned i = 0; i < _SIGSET_NWORDS; i++) - _value[i] = 0; - - /* - * Both '__sigword' and '__sigmask' are macros, defined in the - * glibc header file 'bits/sigset.h' and not external functions. - * Therefore we can use them here without getting into conflicts - * with the linkage of another libc. - */ - _value[__sigword(signum)] = __sigmask(signum); + _value[_word(signum)] = _mask(signum); } - bool is_set(int signum) { - return _value[__sigword(signum)] && __sigmask(signum); } + bool is_set(int signum) + { + return _value[_word(signum)] && _mask(signum); + } }; @@ -396,7 +415,7 @@ class Lx_sigset inline bool lx_sigpending(int signum) { Lx_sigset sigset; - lx_syscall(SYS_rt_sigpending, &sigset, _NSIG/8); + lx_syscall(SYS_rt_sigpending, &sigset, sizeof(sigset)); return sigset.is_set(signum); } @@ -412,7 +431,7 @@ inline bool lx_sigpending(int signum) inline bool lx_sigsetmask(int signum, bool state) { Lx_sigset old_sigmask, sigset(signum); - lx_syscall(SYS_rt_sigprocmask, state ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old_sigmask, _NSIG/8); + lx_syscall(SYS_rt_sigprocmask, state ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old_sigmask, sizeof(sigset)); return old_sigmask.is_set(signum); }