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