killall5.c - ubase - suckless linux base utils
HTML git clone git://git.suckless.org/ubase
DIR Log
DIR Files
DIR Refs
DIR README
DIR 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), 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 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 }