diff options
| author | Mattias Andrée <maandree@kth.se> | 2016-09-30 12:27:09 +0200 | 
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2016-09-30 12:27:09 +0200 | 
| commit | 8965fb661cdc542da9546f6a8e8467f497db3ae6 (patch) | |
| tree | 6a7c68cb32bce3e12b9cad0d1a098be5d47d047e | |
| parent | first commit (diff) | |
| download | pdeath-8965fb661cdc542da9546f6a8e8467f497db3ae6.tar.gz pdeath-8965fb661cdc542da9546f6a8e8467f497db3ae6.tar.bz2 pdeath-8965fb661cdc542da9546f6a8e8467f497db3ae6.tar.xz  | |
add code
Signed-off-by: Mattias Andrée <maandree@kth.se>
| -rw-r--r-- | src/pdeath.c | 170 | 
1 files changed, 170 insertions, 0 deletions
diff --git a/src/pdeath.c b/src/pdeath.c new file mode 100644 index 0000000..2d564a8 --- /dev/null +++ b/src/pdeath.c @@ -0,0 +1,170 @@ +/* See LICENSE file for copyright and license details. */ + +#include <sys/prctl.h> +#include <errno.h> +#include <limits.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> + +#define FAILURE  127 + +struct sig { +	int signo; +	const char *name; +} sigs[] = { +	{SIGHUP,    "HUP"}, +	{SIGINT,    "INT"}, +	{SIGQUIT,   "QUIT"}, +	{SIGILL,    "ILL"}, +	{SIGTRAP,   "TRAP"}, +	{SIGABRT,   "ABRT"}, +	{SIGIOT,    "IOT"}, +	{SIGBUS,    "BUS"}, +	{SIGFPE,    "FPE"}, +	{SIGKILL,   "KILL"}, +	{SIGUSR1,   "USR1"}, +	{SIGSEGV,   "SEGV"}, +	{SIGUSR2,   "USR2"}, +	{SIGPIPE,   "PIPE"}, +	{SIGALRM,   "ALRM"}, +	{SIGTERM,   "TERM"}, +	{SIGSTKFLT, "TKFLT"}, +	{SIGCLD,    "CLD"}, +	{SIGCHLD,   "CHLD"}, +	{SIGCONT,   "CONT"}, +	{SIGSTOP,   "STOP"}, +	{SIGTSTP,   "TSTP"}, +	{SIGTTIN,   "TTIN"}, +	{SIGTTOU,   "TTOU"}, +	{SIGURG,    "URG"}, +	{SIGXCPU,   "XCPU"}, +	{SIGXFSZ,   "XFSZ"}, +	{SIGVTALRM, "VTALRM"}, +	{SIGPROF,   "PROF"}, +	{SIGWINCH,  "WINCH"}, +	{SIGPOLL,   "POLL"}, +	{SIGIO,     "IO"}, +	{SIGPWR,    "PWR"}, +	{SIGSYS,    "SYS"}, +	{SIGUNUSED, "UNUSED"}, +	{0,         NULL} +}; + +const char *argv0; + +static void +usage(void) +{ +	fprintf(stderr, "usage: %s (signal)[(+|-)off] command [arguments]...\n", argv0); +	fprintf(stderr, "usage: %s -L\n", argv0); +	exit(FAILURE); +} + +static void +invalid_signal(void) +{ +	fprintf(stderr, "%s: invalid signal\n", argv0); +	exit(FAILURE); +} + +static void +print_signals(void) +{ +	struct sig *sig = sigs; +	for (; sig->name; sig++) +		printf("%s\n", sig->name); +	printf("RTMIN\nRTMAX\n"); +} + +static int +strict_strtoi(const char *str, int min, int max) +{ +	char *end; +	long int ret; +	errno = 0; +	ret = strtol(str, &end, 10); +	if (errno || *end) +		usage(); +	if (ret < min || ret > max) +		invalid_signal(); +	return (int)ret; +} + +static int +get_signal(const char *str) +{ +	struct sig *sig = sigs; +	int have_prefix = 0; +	char *end; +	long int ret; +	if (!strncasecmp(str, "SIG", 3)) { +		str += 3; +		have_prefix = 1; +	} +	if (!strcasecmp(str, "RTMIN")) +		return SIGRTMIN; +	if (!strcasecmp(str, "RTMAX")) +		return SIGRTMAX; +	for (; sig->name; sig++) { +		if (!strcasecmp(str, sig->name)) +		  return sig->signo; +	} +	if (!have_prefix) { +		errno = 0; +		ret = strtol(str, &end, 10); +		if (!errno && !*end && 0 <= ret && ret < _NSIG) +			return (int)ret; + +	} +	invalid_signal(); +	return -1; +} + +int +main(int argc, char *argv[]) +{ +	char *off; +	char sign = '\0'; +	int signo; + +	argv0 = *argv ? (argc--, *argv++) : "pdeath"; + +	if (*argv && **argv == '-') { +		if (argc == 1 && !strcmp(*argv, "-L")) { +			print_signals(); +			if (fflush(stdout) || fclose(stdout)) { +				perror(argv0); +				return FAILURE; +			} +			return 0; +		} +		usage(); +	} + +	if (argc < 2) +		usage(); + +	if ((off = strpbrk(*argv, "+-"))) { +		sign = *off; +		*off++ = '\0'; +	} +	signo = get_signal(*argv); +	if (sign == '-') +		signo -= strict_strtoi(off, 0, signo); +	else if (sign == '+') +		signo += strict_strtoi(off, 0, _NSIG - 1 - signo); +	argv++, argc--; + +	if (prctl(PR_SET_PDEATHSIG, signo) == -1) { +		perror(argv0); +		return FAILURE; +	} + +	execvp(*argv, argv); +	fprintf(stderr, "%s: %s: %s\n", argv0, strerror(errno), *argv); +	return FAILURE; +}  | 
