diff options
Diffstat (limited to 'src/signals.c')
-rw-r--r-- | src/signals.c | 90 |
1 files changed, 82 insertions, 8 deletions
diff --git a/src/signals.c b/src/signals.c index 390d684..cd23773 100644 --- a/src/signals.c +++ b/src/signals.c @@ -22,6 +22,7 @@ volatile sig_atomic_t exiting = 0; volatile sig_atomic_t disable = 0; +volatile enum signals signals = 0; /** @@ -40,19 +41,19 @@ sigexit(int signo) } +#ifndef WINDOWS + /** * Signal handler for disable signal (SIGUSR1) * * @param signo The received signal */ -#ifndef WINDOWS static void sigdisable(int signo) { disable = 1; (void) signo; } -#endif /** @@ -61,7 +62,6 @@ sigdisable(int signo) * * @param signo The received signal */ -#ifndef WINDOWS static void sigalrm(int signo) { @@ -70,6 +70,71 @@ sigalrm(int signo) exiting = 1; alarm(1U); } + + +/** + * Signal handler for SIGUSR2 + * + * @param signo The received signal + * @param info The received signal data + * @param uctx Interrupted stack context + */ +static void +sigipc(int signo, siginfo_t *info, void *uctx) +{ + int set, mask; + sigset_t sigusr2_mask; + + (void) signo; + (void) uctx; + + if (info->si_code != SI_QUEUE) + return; + + switch (info->si_value.sival_int) { + case 1: + case 2: + mask = 3 << 1; + break; + + case 5: + case 6: + mask = 3 << 5; + break; + + case 7: + case 8: + mask = 3 << 7; + break; + + case 11: + case 12: + mask = 3 << 11; + break; + + case 0: + case 3: + case 4: + case 9: + case 10: + mask = 0; + break; + + default: + return; + } + + signals |= set = 1 << info->si_value.sival_int; + signals &= ~mask | set; + + if (set == SIGNAL_ORDER_BARRIER) { + sigemptyset(&sigusr2_mask); + sigaddset(&sigusr2_mask, SIGUSR2); + if (sigprocmask(SIG_BLOCK, &sigusr2_mask, NULL)) + eprintf("sigprocmask:"); + } +} + #endif @@ -89,23 +154,32 @@ install_signal_handlers(void) memset(&sigact, 0, sizeof(sigact)); sigemptyset(&sigset); sigact.sa_mask = sigset; - sigact.sa_flags = 0; + + sigact.sa_flags = SA_NODEFER; sigact.sa_handler = &sigexit; if (sigaction(SIGINT, &sigact, NULL)) - eprintf("sigaction SIGINT &{.sa_handler=<function pointer>, .sa_mask={}, .sa_flags=0} NULL:"); + eprintf("sigaction SIGINT &{.sa_handler=<function pointer>, .sa_mask={}, .sa_flags=SA_NODEFER} NULL:"); if (sigaction(SIGTERM, &sigact, NULL)) - eprintf("sigaction SIGTERM &{.sa_handler=<function pointer>, .sa_mask={}, .sa_flags=0} NULL:"); + eprintf("sigaction SIGTERM &{.sa_handler=<function pointer>, .sa_mask={}, .sa_flags=SA_NODEFER} NULL:"); if (sigaction(SIGQUIT, &sigact, NULL)) - eprintf("sigaction SIGQUIT &{.sa_handler=<function pointer>, .sa_mask={}, .sa_flags=0} NULL:"); + eprintf("sigaction SIGQUIT &{.sa_handler=<function pointer>, .sa_mask={}, .sa_flags=SA_NODEFER} NULL:"); sigact.sa_handler = &sigdisable; if (sigaction(SIGUSR1, &sigact, NULL)) - eprintf("sigaction SIGUSR1 &{.sa_handler=<function pointer>, .sa_mask={}, .sa_flags=0} NULL:"); + eprintf("sigaction SIGUSR1 &{.sa_handler=<function pointer>, .sa_mask={}, .sa_flags=SA_NODEFER} NULL:"); + + sigact.sa_flags = 0; sigact.sa_handler = SIG_IGN; /* cause child processes (hooks) to be reaped automatically */ if (sigaction(SIGCHLD, &sigact, NULL)) eprintf("sigaction SIGCHLD &{.sa_handler=SIG_IGN, .sa_mask={}, .sa_flags=0} NULL:"); + + sigact.sa_flags = SA_SIGINFO; + + sigact.sa_sigaction = &sigipc; + if (sigaction(SIGUSR2, &sigact, NULL)) + eprintf("sigaction SIGUSR2 &{.sa_sigaction=<function pointer>, .sa_mask={}, .sa_flags=SA_SIGINFO} NULL:"); #endif } |