sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | LICENSE

kill.c (2415B)


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