morpheus-base

morpheus base system
git clone git://git.2f30.org/morpheus-base
Log | Files | Refs

kill.c (2706B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <ctype.h>
      3 #include <errno.h>
      4 #include <signal.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <strings.h>
      9 #include <sys/wait.h>
     10 #include <unistd.h>
     11 
     12 #include "util.h"
     13 
     14 struct {
     15 	const char *name;
     16 	int sig;
     17 } sigs[] = {
     18 	{ "0", 0 },
     19 #define SIG(n) { #n, SIG##n }
     20 	SIG(ABRT), SIG(ALRM), SIG(BUS),  SIG(CHLD), SIG(CONT), SIG(FPE),  SIG(HUP),
     21 	SIG(ILL),  SIG(INT),  SIG(KILL), SIG(PIPE), SIG(QUIT), SIG(SEGV), SIG(STOP),
     22 	SIG(TERM), SIG(TSTP), SIG(TTIN), SIG(TTOU), SIG(USR1), SIG(USR2), SIG(URG),
     23 #undef SIG
     24 };
     25 
     26 const char *sig2name(int);
     27 int name2sig(const char *);
     28 
     29 static void
     30 usage(void)
     31 {
     32 	weprintf("usage: %s [-s signame | -signum | -signame] pid ...\n", argv0);
     33 	weprintf("       %s -l [exit_status]\n", argv0);
     34 	exit(1);
     35 }
     36 
     37 int
     38 main(int argc, char *argv[])
     39 {
     40 	char *end;
     41 	int ret = 0;
     42 	int sig = SIGTERM;
     43 	pid_t pid;
     44 	size_t i;
     45 
     46 	argv0 = argv[0];
     47 	if (argc < 2)
     48 		usage();
     49 
     50 	argc--, argv++;
     51 	if (strcmp(argv[0], "-l") == 0) {
     52 		argc--, argv++;
     53 		if (argc == 0) {
     54 			for (i = 0; i < LEN(sigs); i++)
     55 				puts(sigs[i].name);
     56 			exit(0);
     57 		} else if (argc > 1)
     58 			usage();
     59 		errno = 0;
     60 		sig = strtol(argv[0], &end, 10);
     61 		if (*end != '\0' || errno != 0)
     62 			eprintf("%s: bad signal number\n", argv[0]);
     63 		if (sig > 128)
     64 			sig = WTERMSIG(sig);
     65 		puts(sig2name(sig));
     66 		exit(0);
     67 	}
     68 
     69 	if (strcmp(argv[0], "-s") == 0) {
     70 		argc--, argv++;
     71 		if (argc == 0)
     72 			usage();
     73 		sig = name2sig(argv[0]);
     74 		argc--, argv++;
     75 	} else if (argv[0][0] == '-') {
     76 		if (isdigit(argv[0][1])) {
     77 			/* handle XSI extension -signum */
     78 			errno = 0;
     79 			sig = strtol(&argv[0][1], &end, 10);
     80 			if (*end != '\0' || errno != 0)
     81 				eprintf("%s: bad signal number\n", &argv[0][1]);
     82 			sig2name(sig);
     83 			argc--, argv++;
     84 		} else if (argv[0][1] != '-') {
     85 			/* handle XSI extension -signame */
     86 			sig = name2sig(&argv[0][1]);
     87 			argc--, argv++;
     88 		}
     89 	}
     90 
     91 	if (argc > 0 && strcmp(argv[0], "--") == 0)
     92 		argc--, argv++;
     93 
     94 	if (argc == 0)
     95 		usage();
     96 
     97 	for (; argc; argc--, argv++) {
     98 		errno = 0;
     99 		pid = strtol(argv[0], &end, 10);
    100 		if (*end == '\0' && errno == 0) {
    101 			if (kill(pid, sig) < 0) {
    102 				weprintf("kill %d:", pid);
    103 				ret = 1;
    104 			}
    105 		} else {
    106 			weprintf("%s: bad pid\n", argv[0]);
    107 			ret = 1;
    108 		}
    109 	}
    110 
    111 	exit(ret);
    112 }
    113 
    114 const char *
    115 sig2name(int sig)
    116 {
    117 	size_t i;
    118 
    119 	for (i = 0; i < LEN(sigs); i++)
    120 		if (sigs[i].sig == sig)
    121 			return sigs[i].name;
    122 	eprintf("%d: bad signal number\n", sig);
    123 	/* unreachable */
    124 	return NULL;
    125 }
    126 
    127 int
    128 name2sig(const char *name)
    129 {
    130 	size_t i;
    131 
    132 	for (i = 0; i < LEN(sigs); i++)
    133 		if (strcasecmp(sigs[i].name, name) == 0)
    134 			return sigs[i].sig;
    135 	eprintf("%s: bad signal name\n", name);
    136 	/* unreachable */
    137 	return -1;
    138 }