1*cf5a6c84SAndroid Build Coastguard Worker /* kill.c - a program to send signals to processes
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2012 Daniel Walter <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker *
5*cf5a6c84SAndroid Build Coastguard Worker * See http://opengroup.org/onlinepubs/9699919799/utilities/kill.html
6*cf5a6c84SAndroid Build Coastguard Worker *
7*cf5a6c84SAndroid Build Coastguard Worker * killall5.c - Send signal to all processes outside current session.
8*cf5a6c84SAndroid Build Coastguard Worker *
9*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2014 Ranjan Kumar <[email protected]>
10*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2014 Kyungwan Han <[email protected]>
11*cf5a6c84SAndroid Build Coastguard Worker *
12*cf5a6c84SAndroid Build Coastguard Worker * No Standard
13*cf5a6c84SAndroid Build Coastguard Worker *
14*cf5a6c84SAndroid Build Coastguard Worker * TODO: toysh jobspec support, -n -L
15*cf5a6c84SAndroid Build Coastguard Worker
16*cf5a6c84SAndroid Build Coastguard Worker USE_KILL(NEWTOY(kill, "?ls: ", TOYFLAG_BIN|TOYFLAG_MAYFORK))
17*cf5a6c84SAndroid Build Coastguard Worker USE_KILLALL5(NEWTOY(killall5, "?o*ls: [!lo][!ls]", TOYFLAG_SBIN))
18*cf5a6c84SAndroid Build Coastguard Worker
19*cf5a6c84SAndroid Build Coastguard Worker config KILL
20*cf5a6c84SAndroid Build Coastguard Worker bool "kill"
21*cf5a6c84SAndroid Build Coastguard Worker default y
22*cf5a6c84SAndroid Build Coastguard Worker help
23*cf5a6c84SAndroid Build Coastguard Worker usage: kill [-l [SIGNAL] | -s SIGNAL | -SIGNAL] PID...
24*cf5a6c84SAndroid Build Coastguard Worker
25*cf5a6c84SAndroid Build Coastguard Worker Send signal to process(es).
26*cf5a6c84SAndroid Build Coastguard Worker
27*cf5a6c84SAndroid Build Coastguard Worker -l List signal name(s) and number(s)
28*cf5a6c84SAndroid Build Coastguard Worker -s Send SIGNAL (default SIGTERM)
29*cf5a6c84SAndroid Build Coastguard Worker
30*cf5a6c84SAndroid Build Coastguard Worker config KILLALL5
31*cf5a6c84SAndroid Build Coastguard Worker bool "killall5"
32*cf5a6c84SAndroid Build Coastguard Worker default y
33*cf5a6c84SAndroid Build Coastguard Worker depends on KILL
34*cf5a6c84SAndroid Build Coastguard Worker help
35*cf5a6c84SAndroid Build Coastguard Worker usage: killall5 [-l [SIGNAL]] [-SIGNAL|-s SIGNAL] [-o PID]...
36*cf5a6c84SAndroid Build Coastguard Worker
37*cf5a6c84SAndroid Build Coastguard Worker Send a signal to all processes outside current session.
38*cf5a6c84SAndroid Build Coastguard Worker
39*cf5a6c84SAndroid Build Coastguard Worker -l List signal name(s) and number(s)
40*cf5a6c84SAndroid Build Coastguard Worker -o PID Omit PID
41*cf5a6c84SAndroid Build Coastguard Worker -s Send SIGNAL (default SIGTERM)
42*cf5a6c84SAndroid Build Coastguard Worker */
43*cf5a6c84SAndroid Build Coastguard Worker
44*cf5a6c84SAndroid Build Coastguard Worker // This has to match the filename:
45*cf5a6c84SAndroid Build Coastguard Worker #define FOR_kill
46*cf5a6c84SAndroid Build Coastguard Worker #define FORCE_FLAGS
47*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
48*cf5a6c84SAndroid Build Coastguard Worker
GLOBALS(char * s;struct arg_list * o;)49*cf5a6c84SAndroid Build Coastguard Worker GLOBALS(
50*cf5a6c84SAndroid Build Coastguard Worker char *s;
51*cf5a6c84SAndroid Build Coastguard Worker struct arg_list *o;
52*cf5a6c84SAndroid Build Coastguard Worker )
53*cf5a6c84SAndroid Build Coastguard Worker
54*cf5a6c84SAndroid Build Coastguard Worker // But kill's flags are a subset of killall5's
55*cf5a6c84SAndroid Build Coastguard Worker
56*cf5a6c84SAndroid Build Coastguard Worker #define FOR_killall5
57*cf5a6c84SAndroid Build Coastguard Worker #include "generated/flags.h"
58*cf5a6c84SAndroid Build Coastguard Worker
59*cf5a6c84SAndroid Build Coastguard Worker void kill_main(void)
60*cf5a6c84SAndroid Build Coastguard Worker {
61*cf5a6c84SAndroid Build Coastguard Worker int signum;
62*cf5a6c84SAndroid Build Coastguard Worker char *tmp, **args = toys.optargs;
63*cf5a6c84SAndroid Build Coastguard Worker pid_t pid;
64*cf5a6c84SAndroid Build Coastguard Worker
65*cf5a6c84SAndroid Build Coastguard Worker // list signal(s)
66*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(l)) {
67*cf5a6c84SAndroid Build Coastguard Worker if (*args) {
68*cf5a6c84SAndroid Build Coastguard Worker int signum = sig_to_num(*args);
69*cf5a6c84SAndroid Build Coastguard Worker char *s = 0;
70*cf5a6c84SAndroid Build Coastguard Worker
71*cf5a6c84SAndroid Build Coastguard Worker if (signum>=0) s = num_to_sig(signum&127);
72*cf5a6c84SAndroid Build Coastguard Worker if (isdigit(**args)) puts(s ? s : "UNKNOWN");
73*cf5a6c84SAndroid Build Coastguard Worker else printf("%d\n", signum);
74*cf5a6c84SAndroid Build Coastguard Worker } else list_signals();
75*cf5a6c84SAndroid Build Coastguard Worker
76*cf5a6c84SAndroid Build Coastguard Worker return;
77*cf5a6c84SAndroid Build Coastguard Worker }
78*cf5a6c84SAndroid Build Coastguard Worker
79*cf5a6c84SAndroid Build Coastguard Worker // signal must come before pids, so "kill -9 -1" isn't confusing.
80*cf5a6c84SAndroid Build Coastguard Worker
81*cf5a6c84SAndroid Build Coastguard Worker if (!TT.s && *args && **args=='-') TT.s = *(args++)+1;
82*cf5a6c84SAndroid Build Coastguard Worker if (TT.s) {
83*cf5a6c84SAndroid Build Coastguard Worker char *arg;
84*cf5a6c84SAndroid Build Coastguard Worker int i = strtol(TT.s, &arg, 10);
85*cf5a6c84SAndroid Build Coastguard Worker
86*cf5a6c84SAndroid Build Coastguard Worker if (!*arg) arg = num_to_sig(i);
87*cf5a6c84SAndroid Build Coastguard Worker else arg = TT.s;
88*cf5a6c84SAndroid Build Coastguard Worker
89*cf5a6c84SAndroid Build Coastguard Worker if (!arg || -1 == (signum = sig_to_num(arg)))
90*cf5a6c84SAndroid Build Coastguard Worker error_exit("Unknown signal '%s'", arg);
91*cf5a6c84SAndroid Build Coastguard Worker } else signum = SIGTERM;
92*cf5a6c84SAndroid Build Coastguard Worker
93*cf5a6c84SAndroid Build Coastguard Worker // is it killall5?
94*cf5a6c84SAndroid Build Coastguard Worker if (CFG_KILLALL5 && toys.which->name[4]=='a') {
95*cf5a6c84SAndroid Build Coastguard Worker DIR *dp;
96*cf5a6c84SAndroid Build Coastguard Worker struct dirent *entry;
97*cf5a6c84SAndroid Build Coastguard Worker int pid, sid;
98*cf5a6c84SAndroid Build Coastguard Worker long *olist = 0, ocount = 0;
99*cf5a6c84SAndroid Build Coastguard Worker
100*cf5a6c84SAndroid Build Coastguard Worker // parse omit list
101*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(o)) {
102*cf5a6c84SAndroid Build Coastguard Worker struct arg_list *ptr;
103*cf5a6c84SAndroid Build Coastguard Worker
104*cf5a6c84SAndroid Build Coastguard Worker for (ptr = TT.o; ptr; ptr = ptr->next) ocount++;
105*cf5a6c84SAndroid Build Coastguard Worker olist = xmalloc(ocount*sizeof(long));
106*cf5a6c84SAndroid Build Coastguard Worker ocount = 0;
107*cf5a6c84SAndroid Build Coastguard Worker for (ptr = TT.o; ptr; ptr=ptr->next) olist[ocount++] = atolx(ptr->arg);
108*cf5a6c84SAndroid Build Coastguard Worker }
109*cf5a6c84SAndroid Build Coastguard Worker
110*cf5a6c84SAndroid Build Coastguard Worker sid = getsid(pid = getpid());
111*cf5a6c84SAndroid Build Coastguard Worker
112*cf5a6c84SAndroid Build Coastguard Worker if (!(dp = opendir("/proc"))) {
113*cf5a6c84SAndroid Build Coastguard Worker free(olist);
114*cf5a6c84SAndroid Build Coastguard Worker perror_exit("/proc");
115*cf5a6c84SAndroid Build Coastguard Worker }
116*cf5a6c84SAndroid Build Coastguard Worker while ((entry = readdir(dp))) {
117*cf5a6c84SAndroid Build Coastguard Worker int count, procpid, procsid;
118*cf5a6c84SAndroid Build Coastguard Worker
119*cf5a6c84SAndroid Build Coastguard Worker if (!(procpid = atoi(entry->d_name))) continue;
120*cf5a6c84SAndroid Build Coastguard Worker
121*cf5a6c84SAndroid Build Coastguard Worker snprintf(toybuf, sizeof(toybuf), "/proc/%d/stat", procpid);
122*cf5a6c84SAndroid Build Coastguard Worker if (!readfile(toybuf, toybuf, sizeof(toybuf))) continue;
123*cf5a6c84SAndroid Build Coastguard Worker // command name can have embedded space and/or )
124*cf5a6c84SAndroid Build Coastguard Worker if (!(tmp = strrchr(toybuf, ')'))
125*cf5a6c84SAndroid Build Coastguard Worker || sscanf(tmp, " %*c %*d %*d %d", &procsid) != 1) continue;
126*cf5a6c84SAndroid Build Coastguard Worker if (pid == procpid || sid == procsid || procpid == 1) continue;
127*cf5a6c84SAndroid Build Coastguard Worker
128*cf5a6c84SAndroid Build Coastguard Worker // Check for kernel threads.
129*cf5a6c84SAndroid Build Coastguard Worker snprintf(toybuf, sizeof(toybuf), "/proc/%d/cmdline", procpid);
130*cf5a6c84SAndroid Build Coastguard Worker if (!readfile(toybuf, toybuf, sizeof(toybuf)) || !*toybuf) continue;
131*cf5a6c84SAndroid Build Coastguard Worker
132*cf5a6c84SAndroid Build Coastguard Worker // Check with omit list.
133*cf5a6c84SAndroid Build Coastguard Worker for (count = 0; count < ocount; count++)
134*cf5a6c84SAndroid Build Coastguard Worker if (procpid == olist[count]) break;
135*cf5a6c84SAndroid Build Coastguard Worker if (count != ocount) continue;
136*cf5a6c84SAndroid Build Coastguard Worker
137*cf5a6c84SAndroid Build Coastguard Worker kill(procpid, signum);
138*cf5a6c84SAndroid Build Coastguard Worker }
139*cf5a6c84SAndroid Build Coastguard Worker closedir(dp);
140*cf5a6c84SAndroid Build Coastguard Worker free(olist);
141*cf5a6c84SAndroid Build Coastguard Worker
142*cf5a6c84SAndroid Build Coastguard Worker // is it kill?
143*cf5a6c84SAndroid Build Coastguard Worker } else {
144*cf5a6c84SAndroid Build Coastguard Worker
145*cf5a6c84SAndroid Build Coastguard Worker // "<1" in optstr wouldn't cover this because "-SIGNAL"
146*cf5a6c84SAndroid Build Coastguard Worker if (!*args) help_exit("missing argument");
147*cf5a6c84SAndroid Build Coastguard Worker
148*cf5a6c84SAndroid Build Coastguard Worker while (*args) {
149*cf5a6c84SAndroid Build Coastguard Worker char *arg = *(args++);
150*cf5a6c84SAndroid Build Coastguard Worker
151*cf5a6c84SAndroid Build Coastguard Worker pid = estrtol(arg, &tmp, 10);
152*cf5a6c84SAndroid Build Coastguard Worker if (!errno && *tmp) errno = ESRCH;
153*cf5a6c84SAndroid Build Coastguard Worker if (errno || kill(pid, signum)<0) perror_msg("bad pid '%s'", arg);
154*cf5a6c84SAndroid Build Coastguard Worker }
155*cf5a6c84SAndroid Build Coastguard Worker }
156*cf5a6c84SAndroid Build Coastguard Worker }
157*cf5a6c84SAndroid Build Coastguard Worker
killall5_main(void)158*cf5a6c84SAndroid Build Coastguard Worker void killall5_main(void)
159*cf5a6c84SAndroid Build Coastguard Worker {
160*cf5a6c84SAndroid Build Coastguard Worker kill_main();
161*cf5a6c84SAndroid Build Coastguard Worker }
162