kill.c - sbase - suckless unix tools
(HTM) git clone git://git.suckless.org/sbase
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) 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 }