1 /* kill.c - a program to send signals to processes
3 * Copyright 2012 Daniel Walter <d.walter@0x90.at>
5 * See http://opengroup.org/onlinepubs/9699919799/utilities/kill.html
7 * killall5.c - Send signal to all processes outside current session.
9 * Copyright 2014 Ranjan Kumar <ranjankumar.bth@gmail.com>
10 * Copyright 2014 Kyungwan Han <asura321@gamil.com>
14 USE_KILL(NEWTOY(kill, "?ls: ", TOYFLAG_BIN))
15 USE_KILLALL5(NEWTOY(killall5, "?o*ls: [!lo][!ls]", TOYFLAG_SBIN))
21 usage: kill [-l [SIGNAL] | -s SIGNAL | -SIGNAL] pid...
23 Send signal to process(es).
25 -l List signal name(s) and number(s)
26 -s Send SIGNAL (default SIGTERM)
33 usage: killall5 [-l [SIGNAL]] [-SIGNAL|-s SIGNAL] [-o PID]...
35 Send a signal to all processes outside current session.
37 -l List signal name(s) and number(s)
39 -s send SIGNAL (default SIGTERM)
42 // This has to match the filename:
48 struct arg_list *olist;
51 // But kill's flags are a subset of killall5's
55 #include "generated/flags.h"
60 char *tmp, **args = toys.optargs;
64 if (toys.optflags & FLAG_l) {
66 int signum = sig_to_num(*args);
69 if (signum>=0) s = num_to_sig(signum&127);
70 puts(s ? s : "UNKNOWN");
71 } else sig_to_num(NULL);
75 // signal must come before pids, so "kill -9 -1" isn't confusing.
77 if (!TT.signame && *args && **args=='-') TT.signame=*(args++)+1;
80 int i = strtol(TT.signame, &arg, 10);
81 if (!*arg) arg = num_to_sig(i);
82 else arg = TT.signame;
84 if (!arg || -1 == (signum = sig_to_num(arg)))
85 error_exit("Unknown signal '%s'", arg);
86 } else signum = SIGTERM;
89 if (CFG_KILLALL5 && toys.which->name[4]=='a') {
93 long *olist = 0, ocount = 0;
96 if (toys.optflags & FLAG_o) {
99 for (ptr = TT.olist; ptr; ptr = ptr->next) ocount++;
100 olist = xmalloc(ocount*sizeof(long));
102 for (ptr = TT.olist; ptr; ptr=ptr->next)
103 olist[ocount++] = atolx(ptr->arg);
106 sid = getsid(pid = getpid());
108 if (!(dp = opendir("/proc"))) perror_exit("/proc");
109 while ((entry = readdir(dp))) {
110 int count, procpid, procsid;
112 if (!(procpid = atoi(entry->d_name))) continue;
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;
119 // Check for kernel threads.
120 snprintf(toybuf, sizeof(toybuf), "/proc/%d/cmdline", procpid);
121 if (!readfile(toybuf, toybuf, sizeof(toybuf)) || !*toybuf) continue;
123 // Check with omit list.
124 for (count = 0; count < ocount; count++)
125 if (procpid == olist[count]) break;
126 if (count != ocount) continue;
128 kill(procpid, signum);
130 if (CFG_TOYBOX_FREE) {
138 // "<1" in optstr wouldn't cover this because "-SIGNAL"
139 if (!*args) help_exit("missing argument");
142 char *arg = *(args++);
144 pid = strtol(arg, &tmp, 10);
145 if (*tmp || kill(pid, signum) < 0) error_msg("unknown pid '%s'", arg);
150 void killall5_main(void)