diff options
Diffstat (limited to 'ps.c')
-rw-r--r-- | ps.c | 150 |
1 files changed, 122 insertions, 28 deletions
@@ -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 | |||