lsmod: repair indentation
[oweals/busybox.git] / procps / kill.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Mini kill/killall implementation for busybox
4  *
5  * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
6  * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
7  *
8  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
9  */
10
11 #include "busybox.h"
12
13 int kill_main(int argc, char **argv)
14 {
15         char *arg;
16         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'));
22
23         /* Parse any options */
24         argc--;
25         arg = *++argv;
26
27         if (argc<1 || arg[0]!='-') {
28                 goto do_it_now;
29         }
30
31         /* The -l option, which prints out signal names. */
32         if (arg[1]=='l' && arg[2]=='\0') {
33                 const char *name;
34                 if (argc==1) {
35                         /* Print the whole signal list */
36                         int col = 0;
37                         for (signo = 1; signo<32; signo++) {
38                                 name = get_signame(signo);
39                                 if (isdigit(name[0])) continue;
40                                 if (col > 66) {
41                                         puts("");
42                                         col = 0;
43                                 }
44                                 col += printf("%2d) %-6s", signo, name);
45                         }
46                         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);
57                                 }
58                                 printf("%2d) %s\n", signo, name);
59                         }
60                 }
61                 /* If they specified -l, we are all done */
62                 return EXIT_SUCCESS;
63         }
64
65         /* The -q quiet option */
66         if (killall && arg[1]=='q' && arg[2]=='\0') {
67                 quiet = 1;
68                 arg = *++argv;
69                 argc--;
70                 if (argc<1) bb_show_usage();
71                 if (arg[0]!='-') goto do_it_now;
72         }
73
74         /* -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--;
80
81 do_it_now:
82
83         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 */
106         if (argc<1)
107                 bb_show_usage();
108
109         if (killall) {
110                 /* Looks like they want to do a killall.  Do that */
111                 pid = getpid();
112                 while (arg) {
113                         long* pidList;
114
115                         pidList = find_pid_by_name(arg);
116                         if (!pidList || *pidList<=0) {
117                                 errors++;
118                                 if (!quiet)
119                                         bb_error_msg("%s: no process killed", arg);
120                         } else {
121                                 long *pl;
122
123                                 for (pl = pidList; *pl!=0; pl++) {
124                                         if (*pl==pid)
125                                                 continue;
126                                         if (kill(*pl, signo)!=0) {
127                                                 errors++;
128                                                 if (!quiet)
129                                                         bb_perror_msg("cannot kill pid %ld", *pl);
130                                         }
131                                 }
132                         }
133                         free(pidList);
134                         arg = *++argv;
135                 }
136                 return errors;
137         }
138
139         /* 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         }
151         return errors;
152 }