Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/procps/kill.c

Parent Directory Parent Directory | Revision Log 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)
-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     }