Dmitry V. Levin
38593e942a
The sigset_t provided by libc is not quite convenient. In glibc, sigset_t is an array with space for 1024 bits, which is much more than required: all architectures supported by Linux have only 64 signals except MIPS, which has 128. In bionic libc, LP32 sigset_t is only 4 bytes long, which is less than necessary. With this change, signal mask is decoded without use of intermediate sigset_t structure, which saves us some cpu cycles in case of glibc with its inflated sigset_t, and enables build with libcs where sigset_t is broken. Old implementation used to check each signal number in the given signal mask twice using sigismember(). New implementation is based on popcount and next_set_bit() so it's noticeably faster. * configure.ac: Check for __builtin_popcount. * signal.c: Ensure that NSIG >= 32. (sprintsigmask, sprintsigmask_long, printsigmask): Remove. (popcount32, sprintsigmask_n): New functions. (tprintsigmask_addr, sprintsigmask_val, tprintsigmask_val): New macros. (print_sigset_addr_len, sys_sigsetmask, sys_sigreturn, sys_siggetmask, sys_sigsuspend, sys_sigprocmask, decode_new_sigaction): Update to use new signal mask decoding interface. * tests/sigaction.c (main): Add a test with almost filled signal mask. * tests/sigaction.awk: Update.
41 lines
794 B
C
41 lines
794 B
C
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
|
|
static void handle_signal(int no)
|
|
{
|
|
_exit(128 + no);
|
|
}
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
struct sigaction sa, sa0;
|
|
|
|
sa.sa_handler = SIG_IGN;
|
|
sigemptyset(&sa.sa_mask);
|
|
sigaddset(&sa.sa_mask, SIGHUP);
|
|
sigaddset(&sa.sa_mask, SIGINT);
|
|
sa.sa_flags = SA_RESTART;
|
|
assert(!sigaction(SIGUSR2, &sa, &sa0));
|
|
|
|
sa.sa_handler = handle_signal;
|
|
sigemptyset(&sa.sa_mask);
|
|
sigaddset(&sa.sa_mask, SIGQUIT);
|
|
sigaddset(&sa.sa_mask, SIGTERM);
|
|
sa.sa_flags = SA_SIGINFO;
|
|
assert(!sigaction(SIGUSR2, &sa, &sa0));
|
|
|
|
sa.sa_handler = SIG_DFL;
|
|
sigemptyset(&sa.sa_mask);
|
|
sa.sa_flags = 0;
|
|
assert(!sigaction(SIGUSR2, &sa, &sa0));
|
|
|
|
sigfillset(&sa.sa_mask);
|
|
sigdelset(&sa.sa_mask, SIGHUP);
|
|
assert(!sigaction(SIGUSR2, &sa, &sa0));
|
|
|
|
return 0;
|
|
}
|