diff options
author | Ron Yorston <rmy@pobox.com> | 2012-03-23 11:13:23 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2012-03-23 11:13:23 +0000 |
commit | 40514a0309939f2446f0d4ed9600cad5de396e7f (patch) | |
tree | 0f5f4a57d4bb7893418b5bb11d482858eb17ba8b /procps | |
parent | 9db164d6e39050d09f38288c6045cd2a2cbf6d63 (diff) | |
parent | c0cae52662ccced9df19f19ec94238d1b1e3bd71 (diff) | |
download | busybox-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.src | 10 | ||||
-rw-r--r-- | procps/nmeter.c | 50 | ||||
-rw-r--r-- | procps/ps.c | 108 | ||||
-rw-r--r-- | procps/smemcap.c | 2 | ||||
-rw-r--r-- | procps/top.c | 2 |
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 | |||
90 | config FEATURE_PS_WIDE | 90 | config 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 | ||
99 | config 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 | |||
99 | config FEATURE_PS_TIME | 107 | config 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. | ||
277 | static int rdval_diskstats(const char* p, ullong *vec) | 279 | static 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 */ |
61 | enum { MAX_WIDTH = 2*1024 }; | 70 | enum { 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 | ||
25 | struct fileblock { | 25 | struct 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 | ||
147 | enum { | 147 | enum { |
148 | OPT_d = (1 << 0), | 148 | OPT_d = (1 << 0), |