kill.c - 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),… | |
20 SIG(ILL), SIG(INT), SIG(KILL), SIG(PIPE), SIG(QUIT), SIG(SEGV)… | |
21 SIG(TERM), SIG(TRAP), SIG(TSTP), SIG(TTIN), SIG(TTOU), SIG(USR1)… | |
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 } |