|  | #include "sigchain.h" | 
|  | #include "cache.h" | 
|  |  | 
|  | #define SIGCHAIN_MAX_SIGNALS 32 | 
|  |  | 
|  | struct sigchain_signal { | 
|  | sigchain_fun *old; | 
|  | int n; | 
|  | int alloc; | 
|  | }; | 
|  | static struct sigchain_signal signals[SIGCHAIN_MAX_SIGNALS]; | 
|  |  | 
|  | static void check_signum(int sig) | 
|  | { | 
|  | if (sig < 1 || sig >= SIGCHAIN_MAX_SIGNALS) | 
|  | die("BUG: signal out of range: %d", sig); | 
|  | } | 
|  |  | 
|  | static int sigchain_push(int sig, sigchain_fun f) | 
|  | { | 
|  | struct sigchain_signal *s = signals + sig; | 
|  | check_signum(sig); | 
|  |  | 
|  | ALLOC_GROW(s->old, s->n + 1, s->alloc); | 
|  | s->old[s->n] = signal(sig, f); | 
|  | if (s->old[s->n] == SIG_ERR) | 
|  | return -1; | 
|  | s->n++; | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | int sigchain_pop(int sig) | 
|  | { | 
|  | struct sigchain_signal *s = signals + sig; | 
|  | check_signum(sig); | 
|  | if (s->n < 1) | 
|  | return 0; | 
|  |  | 
|  | if (signal(sig, s->old[s->n - 1]) == SIG_ERR) | 
|  | return -1; | 
|  | s->n--; | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | void sigchain_push_common(sigchain_fun f) | 
|  | { | 
|  | sigchain_push(SIGINT, f); | 
|  | sigchain_push(SIGHUP, f); | 
|  | sigchain_push(SIGTERM, f); | 
|  | sigchain_push(SIGQUIT, f); | 
|  | sigchain_push(SIGPIPE, f); | 
|  | } |