Mercurial > hg > toybox
comparison toys/posix/kill.c @ 1381:cae43f3cfff4 draft
Promote killall5 by merging it into kill.
Slight conflict here: this puts killall5 in the posix directory. But the commands sharing code trumps that.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sun, 06 Jul 2014 19:14:05 -0500 |
parents | 6cc69be43c42 |
children |
comparison
equal
deleted
inserted
replaced
1380:9748833918b0 | 1381:cae43f3cfff4 |
---|---|
1 /* kill.c - a program to send signals to processes | 1 /* kill.c - a program to send signals to processes |
2 * | 2 * |
3 * Copyright 2012 Daniel Walter <d.walter@0x90.at> | 3 * Copyright 2012 Daniel Walter <d.walter@0x90.at> |
4 * | 4 * |
5 * See http://opengroup.org/onlinepubs/9699919799/utilities/kill.html | 5 * See http://opengroup.org/onlinepubs/9699919799/utilities/kill.html |
6 * | |
7 * killall5.c - Send signal to all processes outside current session. | |
8 * | |
9 * Copyright 2014 Ranjan Kumar <ranjankumar.bth@gmail.com> | |
10 * Copyright 2014 Kyungwan Han <asura321@gamil.com> | |
11 * | |
12 * No Standard | |
6 | 13 |
7 USE_KILL(NEWTOY(kill, "?s: l", TOYFLAG_BIN)) | 14 USE_KILL(NEWTOY(kill, "?ls: ", TOYFLAG_BIN)) |
15 USE_KILLALL5(NEWTOY(killall5, "?o*ls: [!lo][!ls]", TOYFLAG_SBIN)) | |
8 | 16 |
9 config KILL | 17 config KILL |
10 bool "kill" | 18 bool "kill" |
11 default y | 19 default y |
12 help | 20 help |
13 usage: kill [-l [SIGNAL] | -s SIGNAL | -SIGNAL] pid... | 21 usage: kill [-l [SIGNAL] | -s SIGNAL | -SIGNAL] pid... |
14 | 22 |
15 Send a signal to a process | 23 Send signal to process(es). |
24 | |
25 -l List signal name(s) and number(s) | |
26 -s Send SIGNAL (default SIGTERM) | |
27 | |
28 config KILLALL5 | |
29 bool "killall5" | |
30 default y | |
31 depends on KILL | |
32 help | |
33 usage: killall5 [-l [SIGNAL]] [-SIGNAL|-s SIGNAL] [-o PID]... | |
34 | |
35 Send a signal to all processes outside current session. | |
36 | |
37 -l List signal name(s) and number(s) | |
38 -o PID Omit PID | |
39 -s send SIGNAL (default SIGTERM) | |
16 */ | 40 */ |
17 | 41 |
42 // This has to match the filename: | |
18 #define FOR_kill | 43 #define FOR_kill |
19 #include "toys.h" | 44 #include "toys.h" |
20 | 45 |
21 GLOBALS( | 46 GLOBALS( |
22 char *signame; | 47 char *signame; |
48 struct arg_list *olist; | |
23 ) | 49 ) |
50 | |
51 // But kill's flags are a subset of killall5's | |
52 | |
53 #define CLEANUP_kill | |
54 #define FOR_killall5 | |
55 #include "generated/flags.h" | |
24 | 56 |
25 void kill_main(void) | 57 void kill_main(void) |
26 { | 58 { |
27 int signum; | 59 int signum; |
28 char *tmp, **args = toys.optargs; | 60 char *tmp, **args = toys.optargs; |
51 | 83 |
52 if (!arg || -1 == (signum = sig_to_num(arg))) | 84 if (!arg || -1 == (signum = sig_to_num(arg))) |
53 error_exit("Unknown signal '%s'", arg); | 85 error_exit("Unknown signal '%s'", arg); |
54 } else signum = SIGTERM; | 86 } else signum = SIGTERM; |
55 | 87 |
56 if (!*args) { | 88 // is it killall5? |
57 toys.exithelp++; | 89 if (CFG_KILLALL5 && toys.which->name[4]=='a') { |
58 error_exit("missing argument"); | 90 DIR *dp; |
59 } | 91 struct dirent *entry; |
92 int pid, sid; | |
93 long *olist = 0, ocount = 0; | |
60 | 94 |
61 while (*args) { | 95 // parse omit list |
62 char *arg = *(args++); | 96 if (toys.optflags & FLAG_o) { |
97 struct arg_list *ptr; | |
63 | 98 |
64 pid = strtol(arg, &tmp, 10); | 99 for (ptr = TT.olist; ptr; ptr = ptr->next) ocount++; |
65 if (*tmp || kill(pid, signum) < 0) error_msg("unknown pid '%s'", arg); | 100 olist = xmalloc(ocount*sizeof(long)); |
101 ocount = 0; | |
102 for (ptr = TT.olist; ptr; ptr=ptr->next) | |
103 olist[ocount++] = atolx(ptr->arg); | |
104 } | |
105 | |
106 sid = getsid(pid = getpid()); | |
107 | |
108 if (!(dp = opendir("/proc"))) perror_exit("/proc"); | |
109 while ((entry = readdir(dp))) { | |
110 int count, procpid, procsid; | |
111 | |
112 if (!(procpid = atoi(entry->d_name))) continue; | |
113 | |
114 snprintf(toybuf, sizeof(toybuf), "/proc/%d/stat", procpid); | |
115 if (!readfile(toybuf, toybuf, sizeof(toybuf))) continue; | |
116 if (sscanf(toybuf, "%*d %*s %*c %*d %*d %d", &procsid) != 1) continue; | |
117 if (pid == procpid || sid == procsid || procpid == 1) continue; | |
118 | |
119 // Check for kernel threads. | |
120 snprintf(toybuf, sizeof(toybuf), "/proc/%d/cmdline", procpid); | |
121 if (!readfile(toybuf, toybuf, sizeof(toybuf)) || !*toybuf) continue; | |
122 | |
123 // Check with omit list. | |
124 for (count = 0; count < ocount; count++) | |
125 if (procpid == olist[count]) break; | |
126 if (count != ocount) continue; | |
127 | |
128 kill(procpid, signum); | |
129 } | |
130 if (CFG_TOYBOX_FREE) { | |
131 closedir(dp); | |
132 free(olist); | |
133 } | |
134 | |
135 // is it kill? | |
136 } else { | |
137 | |
138 // "<1" in optstr wouldn't cover this because "-SIGNAL" | |
139 if (!*args) { | |
140 toys.exithelp++; | |
141 error_exit("missing argument"); | |
142 } | |
143 | |
144 while (*args) { | |
145 char *arg = *(args++); | |
146 | |
147 pid = strtol(arg, &tmp, 10); | |
148 if (*tmp || kill(pid, signum) < 0) error_msg("unknown pid '%s'", arg); | |
149 } | |
66 } | 150 } |
67 } | 151 } |
152 | |
153 void killall5_main(void) | |
154 { | |
155 kill_main(); | |
156 } |