aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-07-03 22:16:17 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-07-03 22:16:17 +0200
commitfca70a8cce579ce8cc8caf246c22f0c6e6c6e139 (patch)
tree2c17970b64b12c34624a18cf42b2c39a2cb5329d
parentc5d07fba29a477569a96777c9cab73e53b1ddd5c (diff)
downloadbusybox-w32-fca70a8cce579ce8cc8caf246c22f0c6e6c6e139.tar.gz
busybox-w32-fca70a8cce579ce8cc8caf246c22f0c6e6c6e139.tar.bz2
busybox-w32-fca70a8cce579ce8cc8caf246c22f0c6e6c6e139.zip
ps: conditionally support additional -o FIELDs
function old new delta procps_scan 1409 1642 +233 out_spec 220 300 +80 func_ruser - 36 +36 func_rgroup - 36 +36 func_group 13 49 +36 func_nice - 29 +29 buffer_fill_and_print 179 196 +17 send_tree 355 360 +5 mkfs_vfat_main 1604 1609 +5 display_speed 85 90 +5 scriptreplay_main 194 197 +3 find_out_spec 55 58 +3 changepath 192 195 +3 sha1_process_block64 497 484 -13 ------------------------------------------------------------------------------ (add/remove: 3/0 grow/shrink: 10/1 up/down: 491/-13) Total: 478 bytes Signed-off-by: David Krakov <krakov@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--include/libbb.h14
-rw-r--r--libbb/procps.c40
-rw-r--r--procps/Config.in13
-rw-r--r--procps/ps.c41
-rw-r--r--procps/top.c2
5 files changed, 92 insertions, 18 deletions
diff --git a/include/libbb.h b/include/libbb.h
index e1c36a57b..77674f8a2 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1276,6 +1276,11 @@ typedef struct procps_status_t {
1276 unsigned sid; 1276 unsigned sid;
1277 unsigned uid; 1277 unsigned uid;
1278 unsigned gid; 1278 unsigned gid;
1279#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
1280 unsigned ruid;
1281 unsigned rgid;
1282 int niceness;
1283#endif
1279 unsigned tty_major,tty_minor; 1284 unsigned tty_major,tty_minor;
1280#if ENABLE_FEATURE_TOPMEM 1285#if ENABLE_FEATURE_TOPMEM
1281 unsigned long mapped_rw; 1286 unsigned long mapped_rw;
@@ -1296,6 +1301,7 @@ typedef struct procps_status_t {
1296 int last_seen_on_cpu; 1301 int last_seen_on_cpu;
1297#endif 1302#endif
1298} procps_status_t; 1303} procps_status_t;
1304/* flag bits for procps_scan(xx, flags) calls */
1299enum { 1305enum {
1300 PSSCAN_PID = 1 << 0, 1306 PSSCAN_PID = 1 << 0,
1301 PSSCAN_PPID = 1 << 1, 1307 PSSCAN_PPID = 1 << 1,
@@ -1322,16 +1328,16 @@ enum {
1322 ), 1328 ),
1323 IF_SELINUX(PSSCAN_CONTEXT = 1 << 17,) 1329 IF_SELINUX(PSSCAN_CONTEXT = 1 << 17,)
1324 PSSCAN_START_TIME = 1 << 18, 1330 PSSCAN_START_TIME = 1 << 18,
1325 PSSCAN_CPU = 1 << 19, 1331 PSSCAN_CPU = (1 << 19) * ENABLE_FEATURE_TOP_SMP_PROCESS,
1332 PSSCAN_NICE = (1 << 20) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
1333 PSSCAN_RUIDGID = (1 << 21) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
1326 /* These are all retrieved from proc/NN/stat in one go: */ 1334 /* These are all retrieved from proc/NN/stat in one go: */
1327 PSSCAN_STAT = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID 1335 PSSCAN_STAT = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID
1328 /**/ | PSSCAN_COMM | PSSCAN_STATE 1336 /**/ | PSSCAN_COMM | PSSCAN_STATE
1329 /**/ | PSSCAN_VSZ | PSSCAN_RSS 1337 /**/ | PSSCAN_VSZ | PSSCAN_RSS
1330 /**/ | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_START_TIME 1338 /**/ | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_START_TIME
1331 /**/ | PSSCAN_TTY 1339 /**/ | PSSCAN_TTY | PSSCAN_NICE
1332#if ENABLE_FEATURE_TOP_SMP_PROCESS
1333 /**/ | PSSCAN_CPU 1340 /**/ | PSSCAN_CPU
1334#endif
1335}; 1341};
1336//procps_status_t* alloc_procps_scan(void) FAST_FUNC; 1342//procps_status_t* alloc_procps_scan(void) FAST_FUNC;
1337void free_procps_scan(procps_status_t* sp) FAST_FUNC; 1343void free_procps_scan(procps_status_t* sp) FAST_FUNC;
diff --git a/libbb/procps.c b/libbb/procps.c
index 445e709c8..6e122c4d5 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -151,6 +151,16 @@ static unsigned long fast_strtoul_10(char **endptr)
151 *endptr = str + 1; /* We skip trailing space! */ 151 *endptr = str + 1; /* We skip trailing space! */
152 return n; 152 return n;
153} 153}
154
155static long fast_strtol_10(char **endptr)
156{
157 if (**endptr != '-')
158 return fast_strtoul_10(endptr);
159
160 (*endptr)++;
161 return - (long)fast_strtoul_10(endptr);
162}
163
154static char *skip_fields(char *str, int count) 164static char *skip_fields(char *str, int count)
155{ 165{
156 do { 166 do {
@@ -208,7 +218,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
208 if (flags & PSSCAN_UIDGID) { 218 if (flags & PSSCAN_UIDGID) {
209 if (stat(filename, &sb)) 219 if (stat(filename, &sb))
210 break; 220 break;
211 /* Need comment - is this effective or real UID/GID? */ 221 /* Effective UID/GID, not real */
212 sp->uid = sb.st_uid; 222 sp->uid = sb.st_uid;
213 sp->gid = sb.st_gid; 223 sp->gid = sb.st_gid;
214 } 224 }
@@ -293,7 +303,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
293 sp->utime = fast_strtoul_10(&cp); 303 sp->utime = fast_strtoul_10(&cp);
294 sp->stime = fast_strtoul_10(&cp); 304 sp->stime = fast_strtoul_10(&cp);
295 cp = skip_fields(cp, 3); /* cutime, cstime, priority */ 305 cp = skip_fields(cp, 3); /* cutime, cstime, priority */
296 tasknice = fast_strtoul_10(&cp); 306 tasknice = fast_strtol_10(&cp);
297 cp = skip_fields(cp, 2); /* timeout, it_real_value */ 307 cp = skip_fields(cp, 2); /* timeout, it_real_value */
298 sp->start_time = fast_strtoul_10(&cp); 308 sp->start_time = fast_strtoul_10(&cp);
299 /* vsz is in bytes and we want kb */ 309 /* vsz is in bytes and we want kb */
@@ -310,6 +320,10 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
310#endif 320#endif
311#endif /* end of !ENABLE_FEATURE_TOP_SMP_PROCESS */ 321#endif /* end of !ENABLE_FEATURE_TOP_SMP_PROCESS */
312 322
323#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
324 sp->niceness = tasknice;
325#endif
326
313 if (sp->vsz == 0 && sp->state[0] != 'Z') 327 if (sp->vsz == 0 && sp->state[0] != 'Z')
314 sp->state[1] = 'W'; 328 sp->state[1] = 'W';
315 else 329 else
@@ -372,7 +386,29 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
372 fclose(file); 386 fclose(file);
373 } 387 }
374#endif /* TOPMEM */ 388#endif /* TOPMEM */
389#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
390 if (flags & PSSCAN_RUIDGID) {
391 FILE *file;
375 392
393 strcpy(filename_tail, "/status");
394 file = fopen_for_read(filename);
395 if (!file)
396 break;
397 while (fgets(buf, sizeof(buf), file)) {
398 char *tp;
399#define SCAN_TWO(str, name, statement) \
400 if (strncmp(buf, str, sizeof(str)-1) == 0) { \
401 tp = skip_whitespace(buf + sizeof(str)-1); \
402 sscanf(tp, "%u", &sp->name); \
403 statement; \
404 }
405 SCAN_TWO("Uid:", ruid, continue);
406 SCAN_TWO("Gid:", rgid, break);
407#undef SCAN_TWO
408 }
409 fclose(file);
410 }
411#endif /* PS_ADDITIONAL_COLUMNS */
376#if 0 /* PSSCAN_CMD is not used */ 412#if 0 /* PSSCAN_CMD is not used */
377 if (flags & (PSSCAN_CMD|PSSCAN_ARGV0)) { 413 if (flags & (PSSCAN_CMD|PSSCAN_ARGV0)) {
378 free(sp->argv0); 414 free(sp->argv0);
diff --git a/procps/Config.in b/procps/Config.in
index 702442a52..9146ff6bf 100644
--- a/procps/Config.in
+++ b/procps/Config.in
@@ -91,13 +91,13 @@ config PS
91 ps gives a snapshot of the current processes. 91 ps gives a snapshot of the current processes.
92 92
93config FEATURE_PS_WIDE 93config FEATURE_PS_WIDE
94 bool "Enable argument for wide output (-w)" 94 bool "Enable wide output option (-w)"
95 default n 95 default n
96 depends on PS 96 depends on PS
97 help 97 help
98 Support argument 'w' for wide output. 98 Support argument 'w' for wide output.
99 If given once, 132 chars are printed and given more than 99 If given once, 132 chars are printed, and if given more
100 one, the length is unlimited. 100 than once, the length is unlimited.
101 101
102config FEATURE_PS_TIME 102config FEATURE_PS_TIME
103 bool "Enable time and elapsed time output" 103 bool "Enable time and elapsed time output"
@@ -106,6 +106,13 @@ config FEATURE_PS_TIME
106 help 106 help
107 Support -o time and -o etime output specifiers. 107 Support -o time and -o etime output specifiers.
108 108
109config FEATURE_PS_ADDITIONAL_COLUMNS
110 bool "Enable additional ps columns"
111 default n
112 depends on PS && DESKTOP
113 help
114 Support -o rgroup, -o ruser, -o nice output specifiers.
115
109config FEATURE_PS_UNUSUAL_SYSTEMS 116config FEATURE_PS_UNUSUAL_SYSTEMS
110 bool "Support Linux prior to 2.4.0 and non-ELF systems" 117 bool "Support Linux prior to 2.4.0 and non-ELF systems"
111 default n 118 default n
diff --git a/procps/ps.c b/procps/ps.c
index b9a4aef15..4a6b60bdc 100644
--- a/procps/ps.c
+++ b/procps/ps.c
@@ -32,7 +32,7 @@ enum { MAX_WIDTH = 2*1024 };
32 32
33typedef struct { 33typedef struct {
34 uint16_t width; 34 uint16_t width;
35 char name[6]; 35 char name6[6];
36 const char *header; 36 const char *header;
37 void (*f)(char *buf, int size, const procps_status_t *ps); 37 void (*f)(char *buf, int size, const procps_status_t *ps);
38 int ps_flags; 38 int ps_flags;
@@ -174,6 +174,11 @@ static void func_user(char *buf, int size, const procps_status_t *ps)
174#endif 174#endif
175} 175}
176 176
177static void func_group(char *buf, int size, const procps_status_t *ps)
178{
179 safe_strncpy(buf, get_cached_groupname(ps->gid), size+1);
180}
181
177static void func_comm(char *buf, int size, const procps_status_t *ps) 182static void func_comm(char *buf, int size, const procps_status_t *ps)
178{ 183{
179 safe_strncpy(buf, ps->comm, size+1); 184 safe_strncpy(buf, ps->comm, size+1);
@@ -227,6 +232,26 @@ static void func_tty(char *buf, int size, const procps_status_t *ps)
227 snprintf(buf, size+1, "%u,%u", ps->tty_major, ps->tty_minor); 232 snprintf(buf, size+1, "%u,%u", ps->tty_major, ps->tty_minor);
228} 233}
229 234
235
236#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
237
238static void func_rgroup(char *buf, int size, const procps_status_t *ps)
239{
240 safe_strncpy(buf, get_cached_groupname(ps->rgid), size+1);
241}
242
243static void func_ruser(char *buf, int size, const procps_status_t *ps)
244{
245 safe_strncpy(buf, get_cached_username(ps->ruid), size+1);
246}
247
248static void func_nice(char *buf, int size, const procps_status_t *ps)
249{
250 sprintf(buf, "%*d", size, ps->niceness);
251}
252
253#endif /* FEATURE_PS_ADDITIONAL_COLUMNS */
254
230#if ENABLE_FEATURE_PS_TIME 255#if ENABLE_FEATURE_PS_TIME
231static void func_etime(char *buf, int size, const procps_status_t *ps) 256static void func_etime(char *buf, int size, const procps_status_t *ps)
232{ 257{
@@ -276,6 +301,7 @@ static void func_pcpu(char *buf, int size, const procps_status_t *ps)
276static const ps_out_t out_spec[] = { 301static const ps_out_t out_spec[] = {
277// Mandated by POSIX: 302// Mandated by POSIX:
278 { 8 , "user" ,"USER" ,func_user ,PSSCAN_UIDGID }, 303 { 8 , "user" ,"USER" ,func_user ,PSSCAN_UIDGID },
304 { 8 , "group" ,"GROUP" ,func_group ,PSSCAN_UIDGID },
279 { 16 , "comm" ,"COMMAND",func_comm ,PSSCAN_COMM }, 305 { 16 , "comm" ,"COMMAND",func_comm ,PSSCAN_COMM },
280 { 256 , "args" ,"COMMAND",func_args ,PSSCAN_COMM }, 306 { 256 , "args" ,"COMMAND",func_args ,PSSCAN_COMM },
281 { 5 , "pid" ,"PID" ,func_pid ,PSSCAN_PID }, 307 { 5 , "pid" ,"PID" ,func_pid ,PSSCAN_PID },
@@ -284,11 +310,12 @@ static const ps_out_t out_spec[] = {
284#if ENABLE_FEATURE_PS_TIME 310#if ENABLE_FEATURE_PS_TIME
285 { sizeof("ELAPSED")-1, "etime" ,"ELAPSED",func_etime ,PSSCAN_START_TIME }, 311 { sizeof("ELAPSED")-1, "etime" ,"ELAPSED",func_etime ,PSSCAN_START_TIME },
286#endif 312#endif
287// { sizeof("GROUP" )-1, "group" ,"GROUP" ,func_group ,PSSCAN_UIDGID }, 313#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
288// { sizeof("NI" )-1, "nice" ,"NI" ,func_nice ,PSSCAN_ }, 314 { 5 , "nice" ,"NI" ,func_nice ,PSSCAN_NICE },
289// { sizeof("%CPU" )-1, "pcpu" ,"%CPU" ,func_pcpu ,PSSCAN_ }, 315 { 8 , "rgroup","RGROUP" ,func_rgroup,PSSCAN_RUIDGID },
290// { sizeof("RGROUP" )-1, "rgroup","RGROUP" ,func_rgroup,PSSCAN_UIDGID }, 316 { 8 , "ruser" ,"RUSER" ,func_ruser ,PSSCAN_RUIDGID },
291// { sizeof("RUSER" )-1, "ruser" ,"RUSER" ,func_ruser ,PSSCAN_UIDGID }, 317// { 5 , "pcpu" ,"%CPU" ,func_pcpu ,PSSCAN_ },
318#endif
292#if ENABLE_FEATURE_PS_TIME 319#if ENABLE_FEATURE_PS_TIME
293 { 6 , "time" ,"TIME" ,func_time ,PSSCAN_STIME | PSSCAN_UTIME }, 320 { 6 , "time" ,"TIME" ,func_time ,PSSCAN_STIME | PSSCAN_UTIME },
294#endif 321#endif
@@ -311,7 +338,7 @@ static const ps_out_t* find_out_spec(const char *name)
311{ 338{
312 unsigned i; 339 unsigned i;
313 for (i = 0; i < ARRAY_SIZE(out_spec); i++) { 340 for (i = 0; i < ARRAY_SIZE(out_spec); i++) {
314 if (!strcmp(name, out_spec[i].name)) 341 if (!strncmp(name, out_spec[i].name6, 6))
315 return &out_spec[i]; 342 return &out_spec[i];
316 } 343 }
317 bb_error_msg_and_die("bad -o argument '%s'", name); 344 bb_error_msg_and_die("bad -o argument '%s'", name);
diff --git a/procps/top.c b/procps/top.c
index 8738156e1..62b9c1e1b 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -871,9 +871,7 @@ enum {
871 | PSSCAN_UTIME 871 | PSSCAN_UTIME
872 | PSSCAN_STATE 872 | PSSCAN_STATE
873 | PSSCAN_COMM 873 | PSSCAN_COMM
874#if ENABLE_FEATURE_TOP_SMP_PROCESS
875 | PSSCAN_CPU 874 | PSSCAN_CPU
876#endif
877 | PSSCAN_UIDGID, 875 | PSSCAN_UIDGID,
878 TOPMEM_MASK = 0 876 TOPMEM_MASK = 0
879 | PSSCAN_PID 877 | PSSCAN_PID