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