killall5.c - ubase - suckless linux base utils | |
git clone git://git.suckless.org/ubase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
killall5.c (2155B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include <dirent.h> | |
3 #include <limits.h> | |
4 #include <signal.h> | |
5 #include <stdio.h> | |
6 #include <stdlib.h> | |
7 #include <string.h> | |
8 #include <unistd.h> | |
9 | |
10 #include "proc.h" | |
11 #include "queue.h" | |
12 #include "util.h" | |
13 | |
14 struct { | |
15 const char *name; | |
16 int sig; | |
17 } sigs[] = { | |
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(TSTP), SIG(TTIN), SIG(TTOU), SIG(USR1), SIG(USR2)… | |
22 #undef SIG | |
23 }; | |
24 | |
25 struct pidentry { | |
26 pid_t pid; | |
27 SLIST_ENTRY(pidentry) entry; | |
28 }; | |
29 | |
30 static SLIST_HEAD(, pidentry) omitpid_head; | |
31 | |
32 static void | |
33 usage(void) | |
34 { | |
35 eprintf("usage: %s [-o pid1,pid2,..,pidN] [-s signal]\n", argv0); | |
36 } | |
37 | |
38 int | |
39 main(int argc, char *argv[]) | |
40 { | |
41 struct pidentry *pe; | |
42 struct dirent *entry; | |
43 DIR *dp; | |
44 char *p, *arg = NULL; | |
45 char *end, *v; | |
46 int oflag = 0; | |
47 int sig = SIGTERM; | |
48 pid_t pid; | |
49 size_t i; | |
50 | |
51 ARGBEGIN { | |
52 case 's': | |
53 v = EARGF(usage()); | |
54 sig = strtol(v, &end, 0); | |
55 if (*end == '\0') | |
56 break; | |
57 for (i = 0; i < LEN(sigs); i++) { | |
58 if (strcasecmp(v, sigs[i].name) == 0) { | |
59 sig = sigs[i].sig; | |
60 break; | |
61 } | |
62 } | |
63 if (i == LEN(sigs)) | |
64 eprintf("%s: unknown signal\n", v); | |
65 break; | |
66 case 'o': | |
67 oflag = 1; | |
68 arg = EARGF(usage()); | |
69 break; | |
70 default: | |
71 usage(); | |
72 } ARGEND; | |
73 | |
74 SLIST_INIT(&omitpid_head); | |
75 | |
76 if (oflag) { | |
77 for (p = strtok(arg, ","); p; p = strtok(NULL, ",")) { | |
78 pe = emalloc(sizeof(*pe)); | |
79 pe->pid = estrtol(p, 10); | |
80 SLIST_INSERT_HEAD(&omitpid_head, pe, entry); | |
81 } | |
82 } | |
83 | |
84 if (sig != SIGSTOP && sig != SIGCONT) | |
85 kill(-1, SIGSTOP); | |
86 | |
87 if (!(dp = opendir("/proc"))) | |
88 eprintf("opendir /proc:"); | |
89 while ((entry = readdir(dp))) { | |
90 if (pidfile(entry->d_name) == 0) | |
91 continue; | |
92 pid = estrtol(entry->d_name, 10); | |
93 if (pid == 1 || pid == getpid() || | |
94 getsid(pid) == getsid(0) || getsid(pid) == 0) | |
95 continue; | |
96 if (oflag == 1) { | |
97 SLIST_FOREACH(pe, &omitpid_head, entry) | |
98 if (pe->pid == pid) | |
99 break; | |
100 if (pe) | |
101 continue; | |
102 } | |
103 kill(pid, sig); | |
104 } | |
105 closedir(dp); | |
106 | |
107 if (sig != SIGSTOP && sig != SIGCONT) | |
108 kill(-1, SIGCONT); | |
109 | |
110 return 0; | |
111 } |