1 // SPDX-License-Identifier: GPL-2.0 2 #include <signal.h> 3 #include "subcmd-util.h" 4 #include "sigchain.h" 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 21 static int sigchain_push(int sig, sigchain_fun f) 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 } 55