diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index 78b69cde85cee8455c74819d5445d9a98151d1a3..67b0575345eef1b186e6aa7de8734e6a3e5d4fe9 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -115,6 +115,10 @@ void __acquire_ptc(); void __release_ptc(); void __inhibit_ptc(); +void __block_all_sigs(void *); +void __block_app_sigs(void *); +void __restore_sigs(void *); + #define DEFAULT_STACK_SIZE 81920 #define DEFAULT_GUARD_SIZE PAGE_SIZE diff --git a/src/signal/block.c b/src/signal/block.c new file mode 100644 index 0000000000000000000000000000000000000000..d7f6100134572aeaa42131dc001ff287ffc9fbbd --- /dev/null +++ b/src/signal/block.c @@ -0,0 +1,44 @@ +#include "pthread_impl.h" +#include "syscall.h" +#include + +static const unsigned long all_mask[] = { +#if ULONG_MAX == 0xffffffff && _NSIG == 129 + -1UL, -1UL, -1UL, -1UL +#elif ULONG_MAX == 0xffffffff + -1UL, -1UL +#else + -1UL +#endif +}; + +static const unsigned long app_mask[] = { +#if ULONG_MAX == 0xffffffff +#if _NSIG == 65 + 0x7fffffff, 0xfffffffc +#else + 0x7fffffff, 0xfffffffc, -1UL, -1UL +#endif +#else +#if _NSIG == 65 + 0xfffffffc7fffffff +#else + 0xfffffffc7fffffff, -1UL +#endif +#endif +}; + +void __block_all_sigs(void *set) +{ + __syscall(SYS_rt_sigprocmask, SIG_BLOCK, &all_mask, set, _NSIG/8); +} + +void __block_app_sigs(void *set) +{ + __syscall(SYS_rt_sigprocmask, SIG_BLOCK, &app_mask, set, _NSIG/8); +} + +void __restore_sigs(void *set) +{ + __syscall(SYS_rt_sigprocmask, SIG_SETMASK, set, 0, _NSIG/8); +} diff --git a/src/signal/raise.c b/src/signal/raise.c index b24dc7417f46131ed8e8d687db75ac9487e85768..6fa43bef97ee1508c23e1dd1328e588ddcf68cf4 100644 --- a/src/signal/raise.c +++ b/src/signal/raise.c @@ -8,10 +8,10 @@ int raise(int sig) { int pid, tid, ret; sigset_t set; - __syscall(SYS_rt_sigprocmask, SIG_BLOCK, SIGALL_SET, &set, _NSIG/8); + __block_app_sigs(&set); tid = __syscall(SYS_gettid); pid = __syscall(SYS_getpid); ret = syscall(SYS_tgkill, pid, tid, sig); - __syscall(SYS_rt_sigprocmask, SIG_SETMASK, &set, 0, _NSIG/8); + __restore_sigs(&set); return ret; } diff --git a/src/signal/siglongjmp.c b/src/signal/siglongjmp.c index bbdde796bb8f0e8b74bc6ab8d4cb96e19794b767..a7bcca2439e67575c1317bb76e4862d183b58db8 100644 --- a/src/signal/siglongjmp.c +++ b/src/signal/siglongjmp.c @@ -2,10 +2,10 @@ #include #include #include "syscall.h" +#include "pthread_impl.h" _Noreturn void siglongjmp(sigjmp_buf buf, int ret) { - if (buf->__fl) __syscall(SYS_rt_sigprocmask, SIG_SETMASK, - buf->__ss, 0, _NSIG/8); + if (buf->__fl) __restore_sigs(buf->__ss); longjmp(buf->__jb, ret); } diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index 6e49acdc6bb77389de220d2b91e2227702b8b626..6c841be799b1632917c4b318dc0fa8faf4bd3e3a 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -35,7 +35,7 @@ _Noreturn void pthread_exit(void *result) * This is important to ensure that dynamically allocated TLS * is not under-allocated/over-committed, and possibly for other * reasons as well. */ - __syscall(SYS_rt_sigprocmask, SIG_BLOCK, SIGALL_SET, &set, _NSIG/8); + __block_all_sigs(&set); /* Wait to unlock the kill lock, which governs functions like * pthread_kill which target a thread id, until signals have @@ -51,7 +51,7 @@ _Noreturn void pthread_exit(void *result) * stdio cleanup code a consistent state. */ if (a_fetch_add(&libc.threads_minus_1, -1)==0) { libc.threads_minus_1 = 0; - __syscall(SYS_rt_sigprocmask, SIG_SETMASK, &set, 0, _NSIG/8); + __restore_sigs(&set); exit(0); } @@ -94,8 +94,7 @@ static int start(void *p) self->detached = 2; pthread_exit(0); } - __syscall(SYS_rt_sigprocmask, SIG_SETMASK, - self->sigmask, 0, _NSIG/8); + __restore_sigs(self->sigmask); } if (self->unblock_cancel) __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, @@ -202,8 +201,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp } if (attr._a_sched) { do_sched = new->startlock[0] = 1; - __syscall(SYS_rt_sigprocmask, SIG_BLOCK, - SIGALL_SET, new->sigmask, _NSIG/8); + __block_app_sigs(new->sigmask); } new->unblock_cancel = self->cancel; new->canary = self->canary; @@ -214,8 +212,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp __release_ptc(); if (do_sched) { - __syscall(SYS_rt_sigprocmask, SIG_SETMASK, - new->sigmask, 0, _NSIG/8); + __restore_sigs(new->sigmask); } if (ret < 0) {