diff options
| author | Erik Andersen <andersen@codepoet.org> | 2000-03-07 07:41:42 +0000 |
|---|---|---|
| committer | Erik Andersen <andersen@codepoet.org> | 2000-03-07 07:41:42 +0000 |
| commit | 246cc6dddd3df2164e8a925ebd8e9a7bba379253 (patch) | |
| tree | 0b9f317c6b6fdebad4f90fbfde5565e195076ea4 /procps | |
| parent | e916d24805b4a191bc08d2ee31c9247a30f9bc1e (diff) | |
| download | busybox-w32-246cc6dddd3df2164e8a925ebd8e9a7bba379253.tar.gz busybox-w32-246cc6dddd3df2164e8a925ebd8e9a7bba379253.tar.bz2 busybox-w32-246cc6dddd3df2164e8a925ebd8e9a7bba379253.zip | |
Wrote killall.
Adjusted mount, ps, utility.c, etc to handle my nifty new kernel
patches the allow busybox to run perfectly without /proc.
-Erik
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 | |||
