blob: fe9b24200da0d3e74cf38e7012440537c316a24c [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;
18 const int killall = (ENABLE_KILLALL && bb_applet_name[4]=='a'
19 && (!ENABLE_KILLALL5 || bb_applet_name[7]!='5'));
20 const int killall5 = (ENABLE_KILLALL5 && bb_applet_name[4]=='a'
21 && (!ENABLE_KILLALL || bb_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 Vlasenko0bb628f2006-09-27 14:25:33 +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 Vlasenkoa77947f2006-09-27 14:19:16 +000032 if (arg[1]=='l' && arg[2]=='\0') {
33 const char *name;
34 if (argc==1) {
Eric Andersen7d72e792003-07-26 07:41:56 +000035 /* Print the whole signal list */
36 int col = 0;
Denis Vlasenkoa77947f2006-09-27 14:19:16 +000037 for (signo = 1; signo<32; signo++) {
38 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> */
48 while ((arg = *++argv)!=NULL) {
49 if (isdigit(arg[0])) {
50 signo = atoi(arg);
51 name = get_signame(signo);
52 } else {
53 signo = get_signum(arg);
54 if (signo<0)
55 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 Vlasenkoa77947f2006-09-27 14:19:16 +000066 if (killall && arg[1]=='q' && arg[2]=='\0') {
67 quiet = 1;
68 arg = *++argv;
Eric Andersen7d72e792003-07-26 07:41:56 +000069 argc--;
Denis Vlasenkoa77947f2006-09-27 14:19:16 +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]);
76 if (signo<0)
77 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;
85 procps_status_t* p;
86
87 /* kill(-1, sig) on Linux (at least 2.1.x)
88 * might send signal to the calling process too */
89 signal(SIGTERM, SIG_IGN);
90 /* Now stop all processes */
91 kill(-1, SIGSTOP);
92 /* Find out our own session id */
93 pid = getpid();
94 sid = getsid(pid);
95 /* Now kill all processes except our session */
96 while ((p = procps_scan(0))!=0) {
97 if (getsid(p->pid)!=sid && p->pid!=pid && p->pid!=1)
98 kill(p->pid, signo);
99 }
100 /* And let them continue */
101 kill(-1, SIGCONT);
102 return 0;
103 }
104
105 /* Pid or name required for kill/killall */
Denis Vlasenkoa77947f2006-09-27 14:19:16 +0000106 if (argc<1)
"Vladimir N. Oleynik"1e98a072006-01-25 13:21:08 +0000107 bb_show_usage();
108
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000109 if (killall) {
Erik Andersen246cc6d2000-03-07 07:41:42 +0000110 /* Looks like they want to do a killall. Do that */
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000111 pid = getpid();
Denis Vlasenkoa77947f2006-09-27 14:19:16 +0000112 while (arg) {
Eric Andersenb24d6562001-12-06 14:52:32 +0000113 long* pidList;
Erik Andersen246cc6d2000-03-07 07:41:42 +0000114
Denis Vlasenkoa77947f2006-09-27 14:19:16 +0000115 pidList = find_pid_by_name(arg);
Eric Andersen7d72e792003-07-26 07:41:56 +0000116 if (!pidList || *pidList<=0) {
Eric Andersenc38678d2002-09-16 06:22:25 +0000117 errors++;
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000118 if (!quiet)
Denis Vlasenkoa77947f2006-09-27 14:19:16 +0000119 bb_error_msg("%s: no process killed", arg);
Eric Andersen7d72e792003-07-26 07:41:56 +0000120 } else {
121 long *pl;
Glenn L McGrathbb2e9d42002-11-25 22:12:28 +0000122
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000123 for (pl = pidList; *pl!=0; pl++) {
124 if (*pl==pid)
Eric Andersen7d72e792003-07-26 07:41:56 +0000125 continue;
Denis Vlasenkoa77947f2006-09-27 14:19:16 +0000126 if (kill(*pl, signo)!=0) {
Eric Andersen7d72e792003-07-26 07:41:56 +0000127 errors++;
Denis Vlasenkoa77947f2006-09-27 14:19:16 +0000128 if (!quiet)
129 bb_perror_msg("cannot kill pid %ld", *pl);
Eric Andersen80cd3cf2002-07-23 23:45:11 +0000130 }
Eric Andersen7d72e792003-07-26 07:41:56 +0000131 }
Erik Andersen246cc6d2000-03-07 07:41:42 +0000132 }
Eric Andersen44608e92002-10-22 12:21:15 +0000133 free(pidList);
Denis Vlasenkoa77947f2006-09-27 14:19:16 +0000134 arg = *++argv;
Erik Andersene49d5ec2000-02-08 19:58:47 +0000135 }
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000136 return errors;
Eric Andersen3cf52d11999-10-12 22:26:06 +0000137 }
Rob Landleyc9c1a412006-07-12 19:17:55 +0000138
Denis Vlasenko0bb628f2006-09-27 14:25:33 +0000139 /* Looks like they want to do a kill. Do that */
140 while (arg) {
141 if (!isdigit(arg[0]) && arg[0]!='-')
142 bb_error_msg_and_die("bad pid '%s'", arg);
143 pid = strtol(arg, NULL, 0);
144 /* FIXME: better overflow check? */
145 if (kill(pid, signo)!=0) {
146 bb_perror_msg("cannot kill pid %ld", (long)pid);
147 errors++;
148 }
149 arg = *++argv;
150 }
Eric Andersenc38678d2002-09-16 06:22:25 +0000151 return errors;
Eric Andersencc8ed391999-10-05 16:24:54 +0000152}