1 #include <signal.h> 2 #include "subcmd-util.h" 3 #include "sigchain.h" 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 20 static int sigchain_push(int sig, sigchain_fun f) 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 } 54