diff options
Diffstat (limited to 'procps')
-rw-r--r-- | procps/kill.c | 63 | ||||
-rw-r--r-- | procps/ps.c | 150 |
2 files changed, 162 insertions, 51 deletions
diff --git a/procps/kill.c b/procps/kill.c index 516621232..8a99e0f9e 100644 --- a/procps/kill.c +++ b/procps/kill.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "internal.h" | 24 | #include "internal.h" |
25 | #include <stdio.h> | 25 | #include <stdio.h> |
26 | #include <stdlib.h> | 26 | #include <stdlib.h> |
27 | #include <errno.h> | ||
27 | #include <unistd.h> | 28 | #include <unistd.h> |
28 | #include <signal.h> | 29 | #include <signal.h> |
29 | #include <ctype.h> | 30 | #include <ctype.h> |
@@ -35,6 +36,14 @@ static const char *kill_usage = | |||
35 | "Send a signal (default is SIGTERM) to the specified process(es).\n\n" | 36 | "Send a signal (default is SIGTERM) to the specified process(es).\n\n" |
36 | "Options:\n" "\t-l\tList all signal names and numbers.\n\n"; | 37 | "Options:\n" "\t-l\tList all signal names and numbers.\n\n"; |
37 | 38 | ||
39 | static const char *killall_usage = | ||
40 | "killall [-signal] process-name [process-name ...]\n\n" | ||
41 | "Send a signal (default is SIGTERM) to the specified process(es).\n\n" | ||
42 | "Options:\n" "\t-l\tList all signal names and numbers.\n\n"; | ||
43 | |||
44 | |||
45 | #define KILL 0 | ||
46 | #define KILLALL 1 | ||
38 | 47 | ||
39 | struct signal_name { | 48 | struct signal_name { |
40 | const char *name; | 49 | const char *name; |
@@ -120,13 +129,19 @@ const struct signal_name signames[] = { | |||
120 | 129 | ||
121 | extern int kill_main(int argc, char **argv) | 130 | extern int kill_main(int argc, char **argv) |
122 | { | 131 | { |
123 | int sig = SIGTERM; | 132 | int whichApp, sig = SIGTERM; |
133 | const char *appUsage; | ||
134 | |||
135 | /* Figure out what we are trying to do here */ | ||
136 | whichApp = (strcmp(*argv, "killall") == 0)? | ||
137 | KILLALL : KILL; | ||
138 | appUsage = (whichApp == KILLALL)? killall_usage : kill_usage; | ||
124 | 139 | ||
125 | argc--; | 140 | argc--; |
126 | argv++; | 141 | argv++; |
127 | /* Parse any options */ | 142 | /* Parse any options */ |
128 | if (argc < 1) | 143 | if (argc < 1) |
129 | usage(kill_usage); | 144 | usage(appUsage); |
130 | 145 | ||
131 | while (argc > 0 && **argv == '-') { | 146 | while (argc > 0 && **argv == '-') { |
132 | while (*++(*argv)) { | 147 | while (*++(*argv)) { |
@@ -150,7 +165,7 @@ extern int kill_main(int argc, char **argv) | |||
150 | } | 165 | } |
151 | break; | 166 | break; |
152 | case '-': | 167 | case '-': |
153 | usage(kill_usage); | 168 | usage(appUsage); |
154 | default: | 169 | default: |
155 | { | 170 | { |
156 | if (isdigit(**argv)) { | 171 | if (isdigit(**argv)) { |
@@ -186,32 +201,34 @@ extern int kill_main(int argc, char **argv) | |||
186 | 201 | ||
187 | do_it_now: | 202 | do_it_now: |
188 | 203 | ||
189 | while (--argc >= 0) { | 204 | if (whichApp == KILL) { |
190 | int pid; | 205 | /* Looks like they want to do a kill. Do that */ |
191 | struct stat statbuf; | 206 | while (--argc >= 0) { |
192 | char pidpath[20] = "/proc/"; | 207 | int pid; |
193 | 208 | ||
194 | if (!isdigit(**argv)) { | 209 | if (!isdigit(**argv)) |
195 | fprintf(stderr, "bad PID: %s\n", *argv); | 210 | fatalError( "Bad PID: %s\n", strerror(errno)); |
196 | exit(FALSE); | 211 | pid = strtol(*argv, NULL, 0); |
197 | } | 212 | if (kill(pid, sig) != 0) |
198 | pid = atoi(*argv); | 213 | fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno)); |
199 | snprintf(pidpath, 20, "/proc/%s/stat", *argv); | 214 | argv++; |
200 | if (stat(pidpath, &statbuf) != 0) { | ||
201 | fprintf(stderr, "kill: (%d) - No such pid\n", pid); | ||
202 | exit(FALSE); | ||
203 | } | 215 | } |
204 | fprintf(stderr, "sig = %d\n", sig); | 216 | } else { |
205 | if (kill(pid, sig) != 0) { | 217 | /* Looks like they want to do a killall. Do that */ |
206 | perror(*argv); | 218 | while (--argc >= 0) { |
207 | exit(FALSE); | 219 | int pid; |
220 | |||
221 | while((pid = findPidByName( *argv))) { | ||
222 | if (kill(pid, sig) != 0) | ||
223 | fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno)); | ||
224 | } | ||
225 | argv++; | ||
208 | } | 226 | } |
209 | argv++; | ||
210 | } | 227 | } |
228 | |||
211 | exit(TRUE); | 229 | exit(TRUE); |
212 | 230 | ||
213 | 231 | ||
214 | end: | 232 | end: |
215 | fprintf(stderr, "bad signal name: %s\n", *argv); | 233 | fatalError( "bad signal name: %s\n", *argv); |
216 | exit(TRUE); | ||
217 | } | 234 | } |
diff --git a/procps/ps.c b/procps/ps.c index 207cdaa02..b0933ab51 100644 --- a/procps/ps.c +++ b/procps/ps.c | |||
@@ -1,34 +1,47 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini ps implementation for busybox | 3 | * Mini ps implementation(s) for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 1999 by Lineo, inc. Written by Erik Andersen | ||
6 | * <andersen@lineo.com>, <andersee@debian.org> | ||
5 | * | 7 | * |
6 | * Copyright (C) 1999 by Lineo, inc. | ||
7 | * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> | ||
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This contains _two_ implementations of ps for Linux. One uses the |
10 | * it under the terms of the GNU General Public License as published by | 10 | * traditional /proc virtual filesystem, and the other use the devps kernel |
11 | * the Free Software Foundation; either version 2 of the License, or | 11 | * driver (written by Erik Andersen to avoid using /proc thereby saving 100k+). |
12 | * (at your option) any later version. | ||
13 | * | 12 | * |
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | 13 | * |
19 | * You should have received a copy of the GNU General Public License | 14 | * |
20 | * along with this program; if not, write to the Free Software | 15 | * This program is free software; you can redistribute it and/or modify it |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * under the terms of the GNU General Public License as published by the Free |
17 | * Software Foundation; either version 2 of the License, or (at your option) | ||
18 | * any later version. | ||
19 | * | ||
20 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
21 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
22 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
23 | * more details. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License along with | ||
26 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
27 | * Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | 28 | * |
23 | */ | 29 | */ |
24 | 30 | ||
25 | #include "internal.h" | 31 | #include "internal.h" |
32 | #include <stdio.h> | ||
26 | #include <unistd.h> | 33 | #include <unistd.h> |
27 | #include <dirent.h> | 34 | #include <dirent.h> |
28 | #include <stdio.h> | 35 | #include <errno.h> |
29 | #include <fcntl.h> | 36 | #include <fcntl.h> |
30 | #include <ctype.h> | 37 | #include <ctype.h> |
31 | 38 | ||
39 | #if ! defined BB_FEATURE_USE_DEVPS_N_DEVMTAB | ||
40 | |||
41 | /* The following is the first ps implementation -- | ||
42 | * the one using the /proc virtual filesystem. | ||
43 | */ | ||
44 | |||
32 | #if ! defined BB_FEATURE_USE_PROCFS | 45 | #if ! defined BB_FEATURE_USE_PROCFS |
33 | #error Sorry, I depend on the /proc filesystem right now. | 46 | #error Sorry, I depend on the /proc filesystem right now. |
34 | #endif | 47 | #endif |
@@ -105,16 +118,12 @@ extern int ps_main(int argc, char **argv) | |||
105 | char groupName[10] = ""; | 118 | char groupName[10] = ""; |
106 | int i, c; | 119 | int i, c; |
107 | 120 | ||
108 | if (argc > 1 && **(argv + 1) == '-') { | 121 | if (argc > 1 && **(argv + 1) == '-') |
109 | usage | 122 | usage ("ps\n\nReport process status\n\nThis version of ps accepts no options.\n"); |
110 | ("ps\n\nReport process status\n\nThis version of ps accepts no options.\n"); | ||
111 | } | ||
112 | 123 | ||
113 | dir = opendir("/proc"); | 124 | dir = opendir("/proc"); |
114 | if (!dir) { | 125 | if (!dir) |
115 | perror("Can't open /proc"); | 126 | fatalError("Can't open /proc"); |
116 | exit(FALSE); | ||
117 | } | ||
118 | 127 | ||
119 | fprintf(stdout, "%5s %-8s %-3s %5s %s\n", "PID", "Uid", "Gid", | 128 | fprintf(stdout, "%5s %-8s %-3s %5s %s\n", "PID", "Uid", "Gid", |
120 | "State", "Command"); | 129 | "State", "Command"); |
@@ -131,9 +140,9 @@ extern int ps_main(int argc, char **argv) | |||
131 | 140 | ||
132 | /* Make some adjustments as needed */ | 141 | /* Make some adjustments as needed */ |
133 | my_getpwuid(uidName, p.ruid); | 142 | my_getpwuid(uidName, p.ruid); |
134 | my_getgrgid(groupName, p.rgid); | ||
135 | if (*uidName == '\0') | 143 | if (*uidName == '\0') |
136 | sprintf(uidName, "%d", p.ruid); | 144 | sprintf(uidName, "%d", p.ruid); |
145 | my_getgrgid(groupName, p.rgid); | ||
137 | if (*groupName == '\0') | 146 | if (*groupName == '\0') |
138 | sprintf(groupName, "%d", p.rgid); | 147 | sprintf(groupName, "%d", p.rgid); |
139 | 148 | ||
@@ -141,10 +150,8 @@ extern int ps_main(int argc, char **argv) | |||
141 | p.state); | 150 | p.state); |
142 | sprintf(path, "/proc/%s/cmdline", entry->d_name); | 151 | sprintf(path, "/proc/%s/cmdline", entry->d_name); |
143 | file = fopen(path, "r"); | 152 | file = fopen(path, "r"); |
144 | if (file == NULL) { | 153 | if (file == NULL) |
145 | perror(path); | 154 | fatalError("Can't open %s: %s\n", path, strerror(errno)); |
146 | exit(FALSE); | ||
147 | } | ||
148 | i = 0; | 155 | i = 0; |
149 | while (((c = getc(file)) != EOF) && (i < 53)) { | 156 | while (((c = getc(file)) != EOF) && (i < 53)) { |
150 | i++; | 157 | i++; |
@@ -159,3 +166,90 @@ extern int ps_main(int argc, char **argv) | |||
159 | closedir(dir); | 166 | closedir(dir); |
160 | exit(TRUE); | 167 | exit(TRUE); |
161 | } | 168 | } |
169 | |||
170 | |||
171 | #else /* BB_FEATURE_USE_DEVPS_N_DEVMTAB */ | ||
172 | |||
173 | |||
174 | /* The following is the second ps implementation -- | ||
175 | * this one uses the nifty new devps kernel device. | ||
176 | */ | ||
177 | |||
178 | #include <sys/ioctl.h> | ||
179 | #include <linux/devps.h> | ||
180 | |||
181 | |||
182 | extern int ps_main(int argc, char **argv) | ||
183 | { | ||
184 | char device[] = "/dev/ps"; | ||
185 | int i, fd; | ||
186 | pid_t num_pids; | ||
187 | pid_t* pid_array = NULL; | ||
188 | struct pid_info info; | ||
189 | char uidName[10] = ""; | ||
190 | char groupName[10] = ""; | ||
191 | |||
192 | if (argc > 1 && **(argv + 1) == '-') | ||
193 | usage("ps-devps\n\nReport process status\n\nThis version of ps accepts no options.\n\n"); | ||
194 | |||
195 | /* open device */ | ||
196 | fd = open(device, O_RDONLY); | ||
197 | if (fd < 0) | ||
198 | fatalError( "open failed for `%s': %s\n", device, strerror (errno)); | ||
199 | |||
200 | /* Find out how many processes there are */ | ||
201 | if (ioctl (fd, DEVPS_GET_NUM_PIDS, &num_pids)<0) | ||
202 | fatalError( "\nDEVPS_GET_PID_LIST: %s\n", strerror (errno)); | ||
203 | |||
204 | /* Allocate some memory -- grab a few extras just in case | ||
205 | * some new processes start up while we wait. The kernel will | ||
206 | * just ignore any extras if we give it too many, and will trunc. | ||
207 | * the list if we give it too few. */ | ||
208 | pid_array = (pid_t*) calloc( num_pids+10, sizeof(pid_t)); | ||
209 | pid_array[0] = num_pids+10; | ||
210 | |||
211 | /* Now grab the pid list */ | ||
212 | if (ioctl (fd, DEVPS_GET_PID_LIST, pid_array)<0) | ||
213 | fatalError("\nDEVPS_GET_PID_LIST: %s\n", strerror (errno)); | ||
214 | |||
215 | /* Print up a ps listing */ | ||
216 | fprintf(stdout, "%5s %-8s %-3s %5s %s\n", "PID", "Uid", "Gid", | ||
217 | "State", "Command"); | ||
218 | |||
219 | for (i=1; i<pid_array[0] ; i++) { | ||
220 | uidName[0] = '\0'; | ||
221 | groupName[0] = '\0'; | ||
222 | info.pid = pid_array[i]; | ||
223 | |||
224 | if (ioctl (fd, DEVPS_GET_PID_INFO, &info)<0) | ||
225 | fatalError("\nDEVPS_GET_PID_INFO: %s\n", strerror (errno)); | ||
226 | |||
227 | /* Make some adjustments as needed */ | ||
228 | my_getpwuid(uidName, info.euid); | ||
229 | if (*uidName == '\0') | ||
230 | sprintf(uidName, "%ld", info.euid); | ||
231 | my_getgrgid(groupName, info.egid); | ||
232 | if (*groupName == '\0') | ||
233 | sprintf(groupName, "%ld", info.egid); | ||
234 | |||
235 | fprintf(stdout, "%5d %-8s %-8s %c ", info.pid, uidName, groupName, info.state); | ||
236 | |||
237 | if (strlen(info.command_line) > 1) | ||
238 | fprintf(stdout, "%s\n", info.command_line); | ||
239 | else | ||
240 | fprintf(stdout, "[%s]\n", info.name); | ||
241 | |||
242 | } | ||
243 | |||
244 | /* Free memory */ | ||
245 | free( pid_array); | ||
246 | |||
247 | /* close device */ | ||
248 | if (close (fd) != 0) | ||
249 | fatalError("close failed for `%s': %s\n", device, strerror (errno)); | ||
250 | |||
251 | exit (0); | ||
252 | } | ||
253 | |||
254 | #endif /* BB_FEATURE_USE_DEVPS_N_DEVMTAB */ | ||
255 | |||