1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "sigchain.h" 2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "cache.h" 3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define SIGCHAIN_MAX_SIGNALS 32 5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct sigchain_signal { 7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sigchain_fun *old; 8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int n; 9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int alloc; 10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}; 11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic struct sigchain_signal signals[SIGCHAIN_MAX_SIGNALS]; 12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void check_signum(int sig) 14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (sig < 1 || sig >= SIGCHAIN_MAX_SIGNALS) 16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng die("BUG: signal out of range: %d", sig); 17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int sigchain_push(int sig, sigchain_fun f) 20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct sigchain_signal *s = signals + sig; 22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng check_signum(sig); 23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ALLOC_GROW(s->old, s->n + 1, s->alloc); 25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->old[s->n] = signal(sig, f); 26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (s->old[s->n] == SIG_ERR) 27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->n++; 29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint sigchain_pop(int sig) 33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct sigchain_signal *s = signals + sig; 35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng check_signum(sig); 36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (s->n < 1) 37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (signal(sig, s->old[s->n - 1]) == SIG_ERR) 40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->n--; 42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid sigchain_push_common(sigchain_fun f) 46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sigchain_push(SIGINT, f); 48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sigchain_push(SIGHUP, f); 49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sigchain_push(SIGTERM, f); 50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sigchain_push(SIGQUIT, f); 51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng sigchain_push(SIGPIPE, f); 52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 53