aboutsummaryrefslogtreecommitdiff
path: root/procps
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2012-03-23 11:13:23 +0000
committerRon Yorston <rmy@pobox.com>2012-03-23 11:13:23 +0000
commit40514a0309939f2446f0d4ed9600cad5de396e7f (patch)
tree0f5f4a57d4bb7893418b5bb11d482858eb17ba8b /procps
parent9db164d6e39050d09f38288c6045cd2a2cbf6d63 (diff)
parentc0cae52662ccced9df19f19ec94238d1b1e3bd71 (diff)
downloadbusybox-w32-40514a0309939f2446f0d4ed9600cad5de396e7f.tar.gz
busybox-w32-40514a0309939f2446f0d4ed9600cad5de396e7f.tar.bz2
busybox-w32-40514a0309939f2446f0d4ed9600cad5de396e7f.zip
Merge commit 'c0cae52662ccced9df19f19ec94238d1b1e3bd71' into merge
Conflicts: Makefile.flags scripts/basic/fixdep.c
Diffstat (limited to 'procps')
-rw-r--r--procps/Config.src10
-rw-r--r--procps/nmeter.c50
-rw-r--r--procps/ps.c108
-rw-r--r--procps/smemcap.c2
-rw-r--r--procps/top.c2
5 files changed, 140 insertions, 32 deletions
diff --git a/procps/Config.src b/procps/Config.src
index 570b026da..5cd47c84f 100644
--- a/procps/Config.src
+++ b/procps/Config.src
@@ -90,12 +90,20 @@ config PS
90config FEATURE_PS_WIDE 90config FEATURE_PS_WIDE
91 bool "Enable wide output option (-w)" 91 bool "Enable wide output option (-w)"
92 default y 92 default y
93 depends on PS 93 depends on PS && !DESKTOP
94 help 94 help
95 Support argument 'w' for wide output. 95 Support argument 'w' for wide output.
96 If given once, 132 chars are printed, and if given more 96 If given once, 132 chars are printed, and if given more
97 than once, the length is unlimited. 97 than once, the length is unlimited.
98 98
99config FEATURE_PS_LONG
100 bool "Enable long output option (-l)"
101 default y
102 depends on PS && !DESKTOP
103 help
104 Support argument 'l' for long output.
105 Adds fields PPID, RSS, START, TIME & TTY
106
99config FEATURE_PS_TIME 107config FEATURE_PS_TIME
100 bool "Enable time and elapsed time output" 108 bool "Enable time and elapsed time output"
101 default y 109 default y
diff --git a/procps/nmeter.c b/procps/nmeter.c
index 999955982..ed5479024 100644
--- a/procps/nmeter.c
+++ b/procps/nmeter.c
@@ -274,30 +274,56 @@ static int rdval_loadavg(const char* p, ullong *vec, ...)
274// 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14 274// 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14
275// 3 0 hda 51292 14441 841783 926052 25717 79650 843256 3029804 0 148459 3956933 275// 3 0 hda 51292 14441 841783 926052 25717 79650 843256 3029804 0 148459 3956933
276// 3 1 hda1 0 0 0 0 <- ignore if only 4 fields 276// 3 1 hda1 0 0 0 0 <- ignore if only 4 fields
277// Linux 3.0 (maybe earlier) started printing full stats for hda1 too.
278// Had to add code which skips such devices.
277static int rdval_diskstats(const char* p, ullong *vec) 279static int rdval_diskstats(const char* p, ullong *vec)
278{ 280{
279 ullong rd = rd; // for compiler 281 char devname[32];
280 int indexline = 0; 282 unsigned devname_len = 0;
283 int value_idx = 0;
284
281 vec[0] = 0; 285 vec[0] = 0;
282 vec[1] = 0; 286 vec[1] = 0;
283 while (1) { 287 while (1) {
284 indexline++; 288 value_idx++;
285 while (*p == ' ' || *p == '\t') p++; 289 while (*p == ' ' || *p == '\t')
286 if (*p == '\0') break; 290 p++;
291 if (*p == '\0')
292 break;
287 if (*p == '\n') { 293 if (*p == '\n') {
288 indexline = 0; 294 value_idx = 0;
289 p++; 295 p++;
290 continue; 296 continue;
291 } 297 }
292 if (indexline == 6) { 298 if (value_idx == 3) {
293 rd = strtoull(p, NULL, 10); 299 char *end = strchrnul(p, ' ');
294 } else if (indexline == 10) { 300 /* If this a hda1-like device (same prefix as last one + digit)? */
295 vec[0] += rd; // TODO: *sectorsize (don't know how to find out sectorsize) 301 if (devname_len && strncmp(devname, p, devname_len) == 0 && isdigit(p[devname_len])) {
302 p = end;
303 goto skip_line; /* skip entire line */
304 }
305 /* It is not. Remember the name for future checks */
306 devname_len = end - p;
307 if (devname_len > sizeof(devname)-1)
308 devname_len = sizeof(devname)-1;
309 strncpy(devname, p, devname_len);
310 /* devname[devname_len] = '\0'; - not really needed */
311 p = end;
312 } else
313 if (value_idx == 6) {
314 // TODO: *sectorsize (don't know how to find out sectorsize)
315 vec[0] += strtoull(p, NULL, 10);
316 } else
317 if (value_idx == 10) {
318 // TODO: *sectorsize (don't know how to find out sectorsize)
296 vec[1] += strtoull(p, NULL, 10); 319 vec[1] += strtoull(p, NULL, 10);
297 while (*p != '\n' && *p != '\0') p++; 320 skip_line:
321 while (*p != '\n' && *p != '\0')
322 p++;
298 continue; 323 continue;
299 } 324 }
300 while (*p > ' ') p++; // skip over value 325 while ((unsigned char)(*p) > ' ') // skip over value
326 p++;
301 } 327 }
302 return 0; 328 return 0;
303} 329}
diff --git a/procps/ps.c b/procps/ps.c
index af57f7aee..aa004aa22 100644
--- a/procps/ps.c
+++ b/procps/ps.c
@@ -39,6 +39,12 @@
39//usage: IF_FEATURE_PS_WIDE( 39//usage: IF_FEATURE_PS_WIDE(
40//usage: "\n w Wide output" 40//usage: "\n w Wide output"
41//usage: ) 41//usage: )
42//usage: IF_FEATURE_PS_LONG(
43//usage: "\n l Long output"
44//usage: )
45//usage: IF_FEATURE_SHOW_THREADS(
46//usage: "\n T Show threads"
47//usage: )
42//usage: 48//usage:
43//usage:#endif /* ENABLE_DESKTOP */ 49//usage:#endif /* ENABLE_DESKTOP */
44//usage: 50//usage:
@@ -56,15 +62,15 @@
56//usage: " 2990 andersen andersen R ps\n" 62//usage: " 2990 andersen andersen R ps\n"
57 63
58#include "libbb.h" 64#include "libbb.h"
65#ifdef __linux__
66# include <sys/sysinfo.h>
67#endif
59 68
60/* Absolute maximum on output line length */ 69/* Absolute maximum on output line length */
61enum { MAX_WIDTH = 2*1024 }; 70enum { MAX_WIDTH = 2*1024 };
62 71
63#if ENABLE_DESKTOP 72#if ENABLE_DESKTOP
64 73
65#ifdef __linux__
66# include <sys/sysinfo.h>
67#endif
68#include <sys/times.h> /* for times() */ 74#include <sys/times.h> /* for times() */
69#ifndef AT_CLKTCK 75#ifndef AT_CLKTCK
70# define AT_CLKTCK 17 76# define AT_CLKTCK 17
@@ -635,15 +641,21 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
635 enum { 641 enum {
636 OPT_Z = (1 << 0) * ENABLE_SELINUX, 642 OPT_Z = (1 << 0) * ENABLE_SELINUX,
637 OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS, 643 OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS,
644 OPT_l = (1 << ENABLE_SELINUX) * (1 << ENABLE_FEATURE_SHOW_THREADS) * ENABLE_FEATURE_PS_LONG,
638 }; 645 };
646#if ENABLE_FEATURE_PS_LONG
647 time_t now = now;
648 struct sysinfo info;
649#endif
639 int opts = 0; 650 int opts = 0;
640 /* If we support any options, parse argv */ 651 /* If we support any options, parse argv */
641#if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE 652#if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE || ENABLE_FEATURE_PS_LONG
642# if ENABLE_FEATURE_PS_WIDE 653# if ENABLE_FEATURE_PS_WIDE
643 /* -w is a bit complicated */ 654 /* -w is a bit complicated */
644 int w_count = 0; 655 int w_count = 0;
645 opt_complementary = "-:ww"; 656 opt_complementary = "-:ww";
646 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")"w", &w_count); 657 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")
658 "w", &w_count);
647 /* if w is given once, GNU ps sets the width to 132, 659 /* if w is given once, GNU ps sets the width to 132,
648 * if w is given more than once, it is "unlimited" 660 * if w is given more than once, it is "unlimited"
649 */ 661 */
@@ -658,23 +670,51 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
658# else 670# else
659 /* -w is not supported, only -Z and/or -T */ 671 /* -w is not supported, only -Z and/or -T */
660 opt_complementary = "-"; 672 opt_complementary = "-";
661 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")); 673 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l"));
662# endif 674# endif
663#endif
664 675
665#if ENABLE_SELINUX 676# if ENABLE_SELINUX
666 if ((opts & OPT_Z) && is_selinux_enabled()) { 677 if ((opts & OPT_Z) && is_selinux_enabled()) {
667 psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT 678 psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT
668 | PSSCAN_STATE | PSSCAN_COMM; 679 | PSSCAN_STATE | PSSCAN_COMM;
669 puts(" PID CONTEXT STAT COMMAND"); 680 puts(" PID CONTEXT STAT COMMAND");
670 } else 681 } else
682# endif
683 if (opts & OPT_l) {
684 psscan_flags = PSSCAN_STATE | PSSCAN_UIDGID | PSSCAN_PID | PSSCAN_PPID
685 | PSSCAN_TTY | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_COMM
686 | PSSCAN_VSZ | PSSCAN_RSS;
687/* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html
688 * mandates for -l:
689 * -F Flags (?)
690 * S State
691 * UID,PID,PPID
692 * -C CPU usage
693 * -PRI The priority of the process; higher numbers mean lower priority
694 * -NI Nice value
695 * -ADDR The address of the process (?)
696 * SZ The size in blocks of the core image
697 * -WCHAN The event for which the process is waiting or sleeping
698 * TTY
699 * TIME The cumulative execution time
700 * CMD
701 * We don't show fields marked with '-'.
702 * We show VSZ and RSS instead of SZ.
703 * We also show STIME (standard says that -f shows it, -l doesn't).
704 */
705 puts("S UID PID PPID VSZ RSS TTY STIME TIME CMD");
706#if ENABLE_FEATURE_PS_LONG
707 now = time(NULL);
708 sysinfo(&info);
671#endif 709#endif
672 { 710 }
711 else {
673 puts(" PID USER VSZ STAT COMMAND"); 712 puts(" PID USER VSZ STAT COMMAND");
674 } 713 }
675 if (opts & OPT_T) { 714 if (opts & OPT_T) {
676 psscan_flags |= PSSCAN_TASKS; 715 psscan_flags |= PSSCAN_TASKS;
677 } 716 }
717#endif
678 718
679 p = NULL; 719 p = NULL;
680 while ((p = procps_scan(p, psscan_flags)) != NULL) { 720 while ((p = procps_scan(p, psscan_flags)) != NULL) {
@@ -688,15 +728,49 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
688 } else 728 } else
689#endif 729#endif
690 { 730 {
691 const char *user = get_cached_username(p->uid); 731 char buf6[6];
692 //if (p->vsz == 0) 732 smart_ulltoa5(p->vsz, buf6, " mgtpezy");
693 // len = printf("%5u %-8.8s %s ", 733 buf6[5] = '\0';
694 // p->pid, user, p->state); 734#if ENABLE_FEATURE_PS_LONG
695 //else 735 if (opts & OPT_l) {
736 char bufr[6], stime_str[6];
737 char tty[2 * sizeof(int)*3 + 2];
738 char *endp;
739 unsigned sut = (p->stime + p->utime) / 100;
740 unsigned elapsed = info.uptime - (p->start_time / 100);
741 time_t start = now - elapsed;
742 struct tm *tm = localtime(&start);
743
744 smart_ulltoa5(p->rss, bufr, " mgtpezy");
745 bufr[5] = '\0';
746
747 if (p->tty_major == 136)
748 /* It should be pts/N, not ptsN, but N > 9
749 * will overflow field width...
750 */
751 endp = stpcpy(tty, "pts");
752 else
753 if (p->tty_major == 4) {
754 endp = stpcpy(tty, "tty");
755 if (p->tty_minor >= 64) {
756 p->tty_minor -= 64;
757 *endp++ = 'S';
758 }
759 }
760 else
761 endp = tty + sprintf(tty, "%d:", p->tty_major);
762 strcpy(endp, utoa(p->tty_minor));
763
764 strftime(stime_str, 6, (elapsed >= (24 * 60 * 60)) ? "%b%d" : "%H:%M", tm);
765 stime_str[5] = '\0';
766 // S UID PID PPID VSZ RSS TTY STIME TIME CMD
767 len = printf("%c %5u %5u %5u %5s %5s %-5s %s %02u:%02u:%02u ",
768 p->state[0], p->uid, p->pid, p->ppid, buf6, bufr, tty,
769 stime_str, sut / 3600, (sut % 3600) / 60, sut % 60);
770 } else
771#endif
696 { 772 {
697 char buf6[6]; 773 const char *user = get_cached_username(p->uid);
698 smart_ulltoa5(p->vsz, buf6, " mgtpezy");
699 buf6[5] = '\0';
700 len = printf("%5u %-8.8s %s %s ", 774 len = printf("%5u %-8.8s %s %s ",
701 p->pid, user, buf6, p->state); 775 p->pid, user, buf6, p->state);
702 } 776 }
diff --git a/procps/smemcap.c b/procps/smemcap.c
index e108d88ad..9d1126a49 100644
--- a/procps/smemcap.c
+++ b/procps/smemcap.c
@@ -20,7 +20,7 @@
20//config: a memory usage statistic tool. 20//config: a memory usage statistic tool.
21 21
22#include "libbb.h" 22#include "libbb.h"
23#include "archive.h" 23#include "bb_archive.h"
24 24
25struct fileblock { 25struct fileblock {
26 struct fileblock *next; 26 struct fileblock *next;
diff --git a/procps/top.c b/procps/top.c
index 011bbf183..15eb624cc 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -126,7 +126,6 @@ struct BUG_bad_size {
126 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; 126 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
127 char BUG_line_buf_too_small[LINE_BUF_SIZE > 80 ? 1 : -1]; 127 char BUG_line_buf_too_small[LINE_BUF_SIZE > 80 ? 1 : -1];
128}; 128};
129#define INIT_G() do { } while (0)
130#define top (G.top ) 129#define top (G.top )
131#define ntop (G.ntop ) 130#define ntop (G.ntop )
132#define sort_field (G.sort_field ) 131#define sort_field (G.sort_field )
@@ -143,6 +142,7 @@ struct BUG_bad_size {
143#define num_cpus (G.num_cpus ) 142#define num_cpus (G.num_cpus )
144#define total_pcpu (G.total_pcpu ) 143#define total_pcpu (G.total_pcpu )
145#define line_buf (G.line_buf ) 144#define line_buf (G.line_buf )
145#define INIT_G() do { } while (0)
146 146
147enum { 147enum {
148 OPT_d = (1 << 0), 148 OPT_d = (1 << 0),