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