blob: 18121f06fbc3f267577793c765c59ed75c3d7f8a [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
Eric Andersenc4996011999-10-20 22:08:37 +00002/*
Erik Andersen5661fe02000-04-05 01:00:52 +00003 * Mini kill/killall implementation for busybox
Eric Andersenc4996011999-10-20 22:08:37 +00004 *
5 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
Eric Andersenc7bda1c2004-03-15 08:29:22 +00006 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
Eric Andersenc4996011999-10-20 22:08:37 +00007 *
Bernhard Reutner-Fischere15d7572006-06-02 20:56:16 +00008 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
Eric Andersenc4996011999-10-20 22:08:37 +00009 */
10
Bernhard Reutner-Fischere15d7572006-06-02 20:56:16 +000011#include "busybox.h"
Eric Andersencc8ed391999-10-05 16:24:54 +000012
Rob Landleydfba7412006-03-06 20:47:33 +000013int kill_main(int argc, char **argv)
Eric Andersencc8ed391999-10-05 16:24:54 +000014{
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000015 char *arg;
Denis Vlasenko0bb628f2006-09-27 14:25:33 +000016 pid_t pid;
17 int signo = SIGTERM, errors = 0, quiet = 0;
Denis Vlasenkofa076802006-11-05 00:38:51 +000018 const int killall = (ENABLE_KILLALL && applet_name[4] == 'a'
19 && (!ENABLE_KILLALL5 || applet_name[7] != '5'));
20 const int killall5 = (ENABLE_KILLALL5 && applet_name[4] == 'a'
21 && (!ENABLE_KILLALL || applet_name[7] == '5'));
Eric Andersencc8ed391999-10-05 16:24:54 +000022
Erik Andersene49d5ec2000-02-08 19:58:47 +000023 /* Parse any options */
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000024 argc--;
25 arg = *++argv;
Erik Andersene49d5ec2000-02-08 19:58:47 +000026
Denis Vlasenkofa076802006-11-05 00:38:51 +000027 if (argc < 1 || arg[0] != '-') {
Eric Andersen7d72e792003-07-26 07:41:56 +000028 goto do_it_now;
29 }
30
31 /* The -l option, which prints out signal names. */
Denis Vlasenkofa076802006-11-05 00:38:51 +000032 if (arg[1] == 'l' && arg[2] == '\0') {
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000033 const char *name;
Denis Vlasenkofa076802006-11-05 00:38:51 +000034 if (argc == 1) {
Eric Andersen7d72e792003-07-26 07:41:56 +000035 /* Print the whole signal list */
36 int col = 0;
Denis Vlasenkofa076802006-11-05 00:38:51 +000037 for (signo = 1; signo < 32; signo++) {
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000038 name = get_signame(signo);
39 if (isdigit(name[0])) continue;
40 if (col > 66) {
41 puts("");
Eric Andersen7d72e792003-07-26 07:41:56 +000042 col = 0;
43 }
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000044 col += printf("%2d) %-6s", signo, name);
Eric Andersen80cd3cf2002-07-23 23:45:11 +000045 }
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000046 puts("");
47 } else { /* -l <sig list> */
Denis Vlasenkofa076802006-11-05 00:38:51 +000048 while ((arg = *++argv)) {
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000049 if (isdigit(arg[0])) {
Denis Vlasenko13858992006-10-08 12:49:22 +000050 signo = xatoi_u(arg);
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000051 name = get_signame(signo);
52 } else {
53 signo = get_signum(arg);
Denis Vlasenkofa076802006-11-05 00:38:51 +000054 if (signo < 0)
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000055 bb_error_msg_and_die("unknown signal '%s'", arg);
56 name = get_signame(signo);
Rob Landleyc9c1a412006-07-12 19:17:55 +000057 }
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000058 printf("%2d) %s\n", signo, name);
Eric Andersen7d72e792003-07-26 07:41:56 +000059 }
60 }
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000061 /* If they specified -l, we are all done */
Eric Andersen7d72e792003-07-26 07:41:56 +000062 return EXIT_SUCCESS;
63 }
64
65 /* The -q quiet option */
Denis Vlasenkofa076802006-11-05 00:38:51 +000066 if (killall && arg[1] == 'q' && arg[2] == '\0') {
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000067 quiet = 1;
68 arg = *++argv;
Eric Andersen7d72e792003-07-26 07:41:56 +000069 argc--;
Denis Vlasenkofa076802006-11-05 00:38:51 +000070 if (argc < 1) bb_show_usage();
71 if (arg[0] != '-') goto do_it_now;
Eric Andersencc8ed391999-10-05 16:24:54 +000072 }
Eric Andersen3cf52d11999-10-12 22:26:06 +000073
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000074 /* -SIG */
75 signo = get_signum(&arg[1]);
Denis Vlasenkofa076802006-11-05 00:38:51 +000076 if (signo < 0)
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000077 bb_error_msg_and_die("bad signal name '%s'", &arg[1]);
78 arg = *++argv;
79 argc--;
Eric Andersen7d72e792003-07-26 07:41:56 +000080
Eric Andersen80cd3cf2002-07-23 23:45:11 +000081do_it_now:
Eric Andersenabc0f4f1999-12-08 23:19:36 +000082
Denis Vlasenko0bb628f2006-09-27 14:25:33 +000083 if (killall5) {
84 pid_t sid;
Denis Vlasenko459e4d62006-11-05 00:43:51 +000085 procps_status_t* p = NULL;
Denis Vlasenko0bb628f2006-09-27 14:25:33 +000086
Denis Vlasenkodd539f72006-11-01 20:20:37 +000087// Cannot happen anyway? We don't TERM ourself, we STOP
88// /* kill(-1, sig) on Linux (at least 2.1.x)
89// * might send signal to the calling process too */
90// signal(SIGTERM, SIG_IGN);
Denis Vlasenko0bb628f2006-09-27 14:25:33 +000091 /* Now stop all processes */
92 kill(-1, SIGSTOP);
93 /* Find out our own session id */
94 pid = getpid();
95 sid = getsid(pid);
96 /* Now kill all processes except our session */
Denis Vlasenko459e4d62006-11-05 00:43:51 +000097 while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID))) {
98 if (p->sid != sid && p->pid != pid && p->pid != 1)
Denis Vlasenko0bb628f2006-09-27 14:25:33 +000099 kill(p->pid, signo);
100 }
101 /* And let them continue */
102 kill(-1, SIGCONT);
103 return 0;
104 }
105
106 /* Pid or name required for kill/killall */
Denis Vlasenko35fb5122006-11-01 09:16:49 +0000107 if (argc < 1)
"Vladimir N. Oleynik"1e98a072006-01-25 13:21:08 +0000108 bb_show_usage();
109
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000110 if (killall) {
Erik Andersen246cc6d2000-03-07 07:41:42 +0000111 /* Looks like they want to do a killall. Do that */
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000112 pid = getpid();
Denis Vlasenkoa77947f2006-09-27 14:19:16 +0000113 while (arg) {
Denis Vlasenko35fb5122006-11-01 09:16:49 +0000114 pid_t* pidList;
Erik Andersen246cc6d2000-03-07 07:41:42 +0000115
Denis Vlasenkoa77947f2006-09-27 14:19:16 +0000116 pidList = find_pid_by_name(arg);
Denis Vlasenko35fb5122006-11-01 09:16:49 +0000117 if (*pidList == 0) {
Eric Andersenc38678d2002-09-16 06:22:25 +0000118 errors++;
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000119 if (!quiet)
Denis Vlasenkoa77947f2006-09-27 14:19:16 +0000120 bb_error_msg("%s: no process killed", arg);
Eric Andersen7d72e792003-07-26 07:41:56 +0000121 } else {
Denis Vlasenko35fb5122006-11-01 09:16:49 +0000122 pid_t *pl;
Glenn L McGrathbb2e9d42002-11-25 22:12:28 +0000123
Denis Vlasenko35fb5122006-11-01 09:16:49 +0000124 for (pl = pidList; *pl; pl++) {
125 if (*pl == pid)
Eric Andersen7d72e792003-07-26 07:41:56 +0000126 continue;
Denis Vlasenko35fb5122006-11-01 09:16:49 +0000127 if (kill(*pl, signo) == 0)
128 continue;
129 errors++;
130 if (!quiet)
131 bb_perror_msg("cannot kill pid %u", (unsigned)*pl);
Eric Andersen7d72e792003-07-26 07:41:56 +0000132 }
Erik Andersen246cc6d2000-03-07 07:41:42 +0000133 }
Eric Andersen44608e92002-10-22 12:21:15 +0000134 free(pidList);
Denis Vlasenkoa77947f2006-09-27 14:19:16 +0000135 arg = *++argv;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000136 }
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000137 return errors;
Eric Andersen3cf52d11999-10-12 22:26:06 +0000138 }
Rob Landleyc9c1a412006-07-12 19:17:55 +0000139
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000140 /* Looks like they want to do a kill. Do that */
141 while (arg) {
Denis Vlasenko35fb5122006-11-01 09:16:49 +0000142 /* Huh?
143 if (!isdigit(arg[0]) && arg[0] != '-')
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000144 bb_error_msg_and_die("bad pid '%s'", arg);
Denis Vlasenko35fb5122006-11-01 09:16:49 +0000145 */
Denis Vlasenko13858992006-10-08 12:49:22 +0000146 pid = xatou(arg);
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000147 /* FIXME: better overflow check? */
Denis Vlasenko35fb5122006-11-01 09:16:49 +0000148 if (kill(pid, signo) != 0) {
149 bb_perror_msg("cannot kill pid %u", (unsigned)pid);
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000150 errors++;
151 }
152 arg = *++argv;
153 }
Eric Andersenc38678d2002-09-16 06:22:25 +0000154 return errors;
Eric Andersencc8ed391999-10-05 16:24:54 +0000155}