| 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 | } |