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 }