diff options
Diffstat (limited to 'tools/perf/util/sigchain.c')
| -rw-r--r-- | tools/perf/util/sigchain.c | 52 | 
1 files changed, 52 insertions, 0 deletions
diff --git a/tools/perf/util/sigchain.c b/tools/perf/util/sigchain.c new file mode 100644 index 00000000000..1118b99e57d --- /dev/null +++ b/tools/perf/util/sigchain.c @@ -0,0 +1,52 @@ +#include "sigchain.h" +#include "cache.h" + +#define SIGCHAIN_MAX_SIGNALS 32 + +struct sigchain_signal { +	sigchain_fun *old; +	int n; +	int alloc; +}; +static struct sigchain_signal signals[SIGCHAIN_MAX_SIGNALS]; + +static void check_signum(int sig) +{ +	if (sig < 1 || sig >= SIGCHAIN_MAX_SIGNALS) +		die("BUG: signal out of range: %d", sig); +} + +int sigchain_push(int sig, sigchain_fun f) +{ +	struct sigchain_signal *s = signals + sig; +	check_signum(sig); + +	ALLOC_GROW(s->old, s->n + 1, s->alloc); +	s->old[s->n] = signal(sig, f); +	if (s->old[s->n] == SIG_ERR) +		return -1; +	s->n++; +	return 0; +} + +int sigchain_pop(int sig) +{ +	struct sigchain_signal *s = signals + sig; +	check_signum(sig); +	if (s->n < 1) +		return 0; + +	if (signal(sig, s->old[s->n - 1]) == SIG_ERR) +		return -1; +	s->n--; +	return 0; +} + +void sigchain_push_common(sigchain_fun f) +{ +	sigchain_push(SIGINT, f); +	sigchain_push(SIGHUP, f); +	sigchain_push(SIGTERM, f); +	sigchain_push(SIGQUIT, f); +	sigchain_push(SIGPIPE, f); +}  |