sbase

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

kill.c (2427B)


      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(TRAP), SIG(TSTP), SIG(TTIN), SIG(TTOU), SIG(USR1), SIG(USR2),
     22 	SIG(URG),
     23 #undef SIG
     24 };
     25 
     26 const char *
     27 sig2name(const int sig)
     28 {
     29 	size_t i;
     30 
     31 	for (i = 0; i < LEN(sigs); i++)
     32 		if (sigs[i].sig == sig)
     33 			return sigs[i].name;
     34 	eprintf("%d: bad signal number\n", sig);
     35 
     36 	return NULL; /* not reached */
     37 }
     38 
     39 int
     40 name2sig(const char *name)
     41 {
     42 	size_t i;
     43 
     44 	for (i = 0; i < LEN(sigs); i++)
     45 		if (!strcasecmp(sigs[i].name, name))
     46 			return sigs[i].sig;
     47 	eprintf("%s: bad signal name\n", name);
     48 
     49 	return -1; /* not reached */
     50 }
     51 
     52 static void
     53 usage(void)
     54 {
     55 	eprintf("usage: %s [-s signame | -num | -signame] pid ...\n"
     56 	        "       %s -l [num]\n", argv0, argv0);
     57 }
     58 
     59 int
     60 main(int argc, char *argv[])
     61 {
     62 	pid_t pid;
     63 	size_t i;
     64 	int ret = 0, sig = SIGTERM;
     65 
     66 	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
     67 
     68 	if (!argc)
     69 		usage();
     70 
     71 	if ((*argv)[0] == '-') {
     72 		switch ((*argv)[1]) {
     73 		case 'l':
     74 			if ((*argv)[2])
     75 				goto longopt;
     76 			argc--, argv++;
     77 			if (!argc) {
     78 				for (i = 0; i < LEN(sigs); i++)
     79 					puts(sigs[i].name);
     80 			} else if (argc == 1) {
     81 				sig = estrtonum(*argv, 0, INT_MAX);
     82 				if (sig > 128)
     83 					sig = WTERMSIG(sig);
     84 				puts(sig2name(sig));
     85 			} else {
     86 				usage();
     87 			}
     88 			return fshut(stdout, "<stdout>");
     89 		case 's':
     90 			if ((*argv)[2])
     91 				goto longopt;
     92 			argc--, argv++;
     93 			if (!argc)
     94 				usage();
     95 			sig = name2sig(*argv);
     96 			argc--, argv++;
     97 			break;
     98 		case '-':
     99 			if ((*argv)[2])
    100 				goto longopt;
    101 			argc--, argv++;
    102 			break;
    103 		default:
    104 		longopt:
    105 			/* XSI-extensions -argnum and -argname*/
    106 			if (isdigit((*argv)[1])) {
    107 				sig = estrtonum((*argv) + 1, 0, INT_MAX);
    108 				sig2name(sig);
    109 			} else {
    110 				sig = name2sig((*argv) + 1);
    111 			}
    112 			argc--, argv++;
    113 		}
    114 	}
    115 
    116 	if (argc && !strcmp(*argv, "--"))
    117 		argc--, argv++;
    118 
    119 	if (!argc)
    120 		usage();
    121 
    122 	for (; *argv; argc--, argv++) {
    123 		pid = estrtonum(*argv, INT_MIN, INT_MAX);
    124 		if (kill(pid, sig) < 0) {
    125 			weprintf("kill %d:", pid);
    126 			ret = 1;
    127 		}
    128 	}
    129 
    130 	return ret;
    131 }