Annotation of /trunk/mkinitrd-magellan/busybox/procps/kill.c
Parent Directory | Revision Log
Revision 532 -
(hide annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 3623 byte(s)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 3623 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | niro | 532 | /* 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 && 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')); | ||
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)) { | ||
49 | if (isdigit(arg[0])) { | ||
50 | signo = xatoi_u(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 = NULL; | ||
86 | |||
87 | // 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); | ||
91 | /* 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 */ | ||
97 | while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID))) { | ||
98 | if (p->sid != sid && p->pid != pid && p->pid != 1) | ||
99 | 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 */ | ||
107 | if (argc < 1) | ||
108 | bb_show_usage(); | ||
109 | |||
110 | if (killall) { | ||
111 | /* Looks like they want to do a killall. Do that */ | ||
112 | pid = getpid(); | ||
113 | while (arg) { | ||
114 | pid_t* pidList; | ||
115 | |||
116 | pidList = find_pid_by_name(arg); | ||
117 | if (*pidList == 0) { | ||
118 | errors++; | ||
119 | if (!quiet) | ||
120 | bb_error_msg("%s: no process killed", arg); | ||
121 | } else { | ||
122 | pid_t *pl; | ||
123 | |||
124 | for (pl = pidList; *pl; pl++) { | ||
125 | if (*pl == pid) | ||
126 | continue; | ||
127 | if (kill(*pl, signo) == 0) | ||
128 | continue; | ||
129 | errors++; | ||
130 | if (!quiet) | ||
131 | bb_perror_msg("cannot kill pid %u", (unsigned)*pl); | ||
132 | } | ||
133 | } | ||
134 | free(pidList); | ||
135 | arg = *++argv; | ||
136 | } | ||
137 | return errors; | ||
138 | } | ||
139 | |||
140 | /* Looks like they want to do a kill. Do that */ | ||
141 | while (arg) { | ||
142 | /* Huh? | ||
143 | if (!isdigit(arg[0]) && arg[0] != '-') | ||
144 | bb_error_msg_and_die("bad pid '%s'", arg); | ||
145 | */ | ||
146 | pid = xatou(arg); | ||
147 | /* FIXME: better overflow check? */ | ||
148 | if (kill(pid, signo) != 0) { | ||
149 | bb_perror_msg("cannot kill pid %u", (unsigned)pid); | ||
150 | errors++; | ||
151 | } | ||
152 | arg = *++argv; | ||
153 | } | ||
154 | return errors; | ||
155 | } |