diff options
-rw-r--r-- | procps/Config.src | 10 | ||||
-rw-r--r-- | procps/ps.c | 103 |
2 files changed, 94 insertions, 19 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/ps.c b/procps/ps.c index dcc0f7bd4..c98384d71 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 |
@@ -625,15 +631,21 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
625 | enum { | 631 | enum { |
626 | OPT_Z = (1 << 0) * ENABLE_SELINUX, | 632 | OPT_Z = (1 << 0) * ENABLE_SELINUX, |
627 | OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS, | 633 | OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS, |
634 | OPT_l = (1 << ENABLE_SELINUX) * (1 << ENABLE_FEATURE_SHOW_THREADS) * ENABLE_FEATURE_PS_LONG, | ||
628 | }; | 635 | }; |
636 | #if ENABLE_FEATURE_PS_LONG | ||
637 | time_t now = now; | ||
638 | struct sysinfo info; | ||
639 | #endif | ||
629 | int opts = 0; | 640 | int opts = 0; |
630 | /* If we support any options, parse argv */ | 641 | /* If we support any options, parse argv */ |
631 | #if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE | 642 | #if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE || ENABLE_FEATURE_PS_LONG |
632 | # if ENABLE_FEATURE_PS_WIDE | 643 | # if ENABLE_FEATURE_PS_WIDE |
633 | /* -w is a bit complicated */ | 644 | /* -w is a bit complicated */ |
634 | int w_count = 0; | 645 | int w_count = 0; |
635 | opt_complementary = "-:ww"; | 646 | opt_complementary = "-:ww"; |
636 | opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")"w", &w_count); | 647 | opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l") |
648 | "w", &w_count); | ||
637 | /* if w is given once, GNU ps sets the width to 132, | 649 | /* if w is given once, GNU ps sets the width to 132, |
638 | * if w is given more than once, it is "unlimited" | 650 | * if w is given more than once, it is "unlimited" |
639 | */ | 651 | */ |
@@ -648,23 +660,47 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
648 | # else | 660 | # else |
649 | /* -w is not supported, only -Z and/or -T */ | 661 | /* -w is not supported, only -Z and/or -T */ |
650 | opt_complementary = "-"; | 662 | opt_complementary = "-"; |
651 | opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")); | 663 | opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")); |
652 | # endif | 664 | # endif |
653 | #endif | ||
654 | 665 | ||
655 | #if ENABLE_SELINUX | 666 | # if ENABLE_SELINUX |
656 | if ((opts & OPT_Z) && is_selinux_enabled()) { | 667 | if ((opts & OPT_Z) && is_selinux_enabled()) { |
657 | psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT | 668 | psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT |
658 | | PSSCAN_STATE | PSSCAN_COMM; | 669 | | PSSCAN_STATE | PSSCAN_COMM; |
659 | puts(" PID CONTEXT STAT COMMAND"); | 670 | puts(" PID CONTEXT STAT COMMAND"); |
660 | } else | 671 | } else |
661 | #endif | 672 | # endif |
662 | { | 673 | if (opts & OPT_l) { |
674 | psscan_flags = PSSCAN_STATE | PSSCAN_UIDGID | PSSCAN_PID | PSSCAN_PPID | ||
675 | | PSSCAN_TTY | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_COMM | ||
676 | | PSSCAN_VSZ | PSSCAN_RSS; | ||
677 | /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html | ||
678 | * mandates for -l: | ||
679 | * -F Flags associated with the process (?) | ||
680 | * S The state of the process | ||
681 | * UID,PID,PPID | ||
682 | * -C Processor utilization for scheduling | ||
683 | * -PRI The priority of the process; higher numbers mean lower priority | ||
684 | * -NI Nice value; used in priority computation | ||
685 | * -ADDR The address of the process | ||
686 | * SZ The size in blocks of the core image of the process | ||
687 | * -WCHAN The event for which the process is waiting or sleeping | ||
688 | * TTY | ||
689 | * TIME The cumulative execution time for the process | ||
690 | * CMD | ||
691 | * We don't show fileds marked with '-'. We show VSZ and RSS instead of SZ | ||
692 | */ | ||
693 | puts("S UID PID PPID VSZ RSS TTY TIME CMD"); | ||
694 | now = time(NULL); | ||
695 | sysinfo(&info); | ||
696 | } | ||
697 | else { | ||
663 | puts(" PID USER VSZ STAT COMMAND"); | 698 | puts(" PID USER VSZ STAT COMMAND"); |
664 | } | 699 | } |
665 | if (opts & OPT_T) { | 700 | if (opts & OPT_T) { |
666 | psscan_flags |= PSSCAN_TASKS; | 701 | psscan_flags |= PSSCAN_TASKS; |
667 | } | 702 | } |
703 | #endif | ||
668 | 704 | ||
669 | p = NULL; | 705 | p = NULL; |
670 | while ((p = procps_scan(p, psscan_flags)) != NULL) { | 706 | while ((p = procps_scan(p, psscan_flags)) != NULL) { |
@@ -678,15 +714,46 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
678 | } else | 714 | } else |
679 | #endif | 715 | #endif |
680 | { | 716 | { |
681 | const char *user = get_cached_username(p->uid); | 717 | char buf6[6]; |
682 | //if (p->vsz == 0) | 718 | smart_ulltoa5(p->vsz, buf6, " mgtpezy"); |
683 | // len = printf("%5u %-8.8s %s ", | 719 | buf6[5] = '\0'; |
684 | // p->pid, user, p->state); | 720 | #if ENABLE_FEATURE_PS_LONG |
685 | //else | 721 | if (opts & OPT_l) { |
722 | char bufr[6], strt[6]; | ||
723 | char tty[2 * sizeof(int)*3 + 2]; | ||
724 | char *endp; | ||
725 | unsigned sut = (p->stime + p->utime) / 100; | ||
726 | unsigned elapsed = info.uptime - (p->start_time / 100); | ||
727 | time_t start = now - elapsed; | ||
728 | struct tm *tm = localtime(&start); | ||
729 | |||
730 | smart_ulltoa5(p->rss, bufr, " mgtpezy"); | ||
731 | bufr[5] = '\0'; | ||
732 | |||
733 | if (p->tty_major == 136) | ||
734 | endp = stpcpy(tty, "pts/"); | ||
735 | else | ||
736 | if (p->tty_major == 4) { | ||
737 | endp = stpcpy(tty, "tty"); | ||
738 | if (p->tty_minor >= 64) { | ||
739 | p->tty_minor -= 64; | ||
740 | *endp++ = 'S'; | ||
741 | } | ||
742 | } | ||
743 | else | ||
744 | endp = tty + sprintf(tty, "%d:", p->tty_major); | ||
745 | strcpy(endp, utoa(p->tty_minor)); | ||
746 | |||
747 | strftime(strt, 6, (elapsed >= (24 * 60 * 60)) ? "%b%d" : "%H:%M", tm); | ||
748 | strt[5] = '\0'; | ||
749 | // S UID PID PPID VSZ RSS TTY TIME CMD | ||
750 | len = printf("%c %5u %5u %5u %5s %5s %-5s %02u:%02u:%02u ", | ||
751 | p->state[0], p->uid, p->pid, p->ppid, buf6, bufr, tty, | ||
752 | sut / 3600, (sut % 3600) / 60, sut % 60); | ||
753 | } else | ||
754 | #endif | ||
686 | { | 755 | { |
687 | char buf6[6]; | 756 | const char *user = get_cached_username(p->uid); |
688 | smart_ulltoa5(p->vsz, buf6, " mgtpezy"); | ||
689 | buf6[5] = '\0'; | ||
690 | len = printf("%5u %-8.8s %s %s ", | 757 | len = printf("%5u %-8.8s %s %s ", |
691 | p->pid, user, buf6, p->state); | 758 | p->pid, user, buf6, p->state); |
692 | } | 759 | } |