1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#define FOR_killall
26#include "toys.h"
27
28GLOBALS(
29 char *s;
30
31 int signum;
32 pid_t cur_pid;
33 char **names;
34 short *err;
35 struct int_list { struct int_list *next; int val; } *pids;
36)
37
38static int kill_process(pid_t pid, char *name)
39{
40 int offset = 0;
41
42 if (pid == TT.cur_pid) return 0;
43
44 if (FLAG(i)) {
45 fprintf(stderr, "Signal %s(%d)", name, (int)pid);
46 if (!yesno(0)) return 0;
47 }
48
49 errno = 0;
50 kill(pid, TT.signum);
51 if (FLAG(w)) {
52 struct int_list *new = xmalloc(sizeof(*TT.pids));
53 new->val = pid;
54 new->next = TT.pids;
55 TT.pids = new;
56 }
57 for (;;) {
58 if (TT.names[offset] == name) {
59 TT.err[offset] = errno;
60 break;
61 } else offset++;
62 }
63 if (errno) {
64 if (!FLAG(q)) perror_msg("pid %d", (int)pid);
65 } else if (FLAG(v))
66 printf("Killed %s(%d) with signal %d\n", name, pid, TT.signum);
67
68 return 0;
69}
70
71void killall_main(void)
72{
73 int i;
74
75 TT.names = toys.optargs;
76 TT.signum = SIGTERM;
77
78 if (FLAG(l)) {
79 list_signals();
80 return;
81 }
82
83 if (TT.s || (*TT.names && **TT.names == '-')) {
84 if (0 > (TT.signum = sig_to_num(TT.s ? TT.s : (*TT.names)+1))) {
85 if (FLAG(q)) exit(1);
86 error_exit("Invalid signal");
87 }
88 if (!TT.s) {
89 TT.names++;
90 toys.optc--;
91 }
92 }
93
94 if (!toys.optc) help_exit("no name");
95
96 TT.cur_pid = getpid();
97
98 TT.err = xmalloc(2*toys.optc);
99 for (i=0; i<toys.optc; i++) TT.err[i] = ESRCH;
100 names_to_pid(TT.names, kill_process, 1);
101 for (i=0; i<toys.optc; i++) {
102 if (TT.err[i]) {
103 toys.exitval = 1;
104 errno = TT.err[i];
105 perror_msg_raw(TT.names[i]);
106 }
107 }
108 if (FLAG(w)) {
109 for (;;) {
110 struct int_list *p = TT.pids;
111 int c = 0;
112
113 for (; p; p=p->next) if (kill(p->val, 0) != -1 || errno != ESRCH) ++c;
114 if (!c) break;
115 sleep(1);
116 }
117 }
118 if (CFG_TOYBOX_FREE) {
119 free(TT.err);
120 llist_traverse(TT.pids, free);
121 }
122}
123