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 config FEATURE_PS_WIDE bool "Enable wide output option (-w)" default y - depends on PS + depends on PS && !DESKTOP help Support argument 'w' for wide output. If given once, 132 chars are printed, and if given more than once, the length is unlimited. +config FEATURE_PS_LONG + bool "Enable long output option (-l)" + default y + depends on PS && !DESKTOP + help + Support argument 'l' for long output. + Adds fields PPID, RSS, START, TIME & TTY + config FEATURE_PS_TIME bool "Enable time and elapsed time output" 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 @@ //usage: IF_FEATURE_PS_WIDE( //usage: "\n w Wide output" //usage: ) +//usage: IF_FEATURE_PS_LONG( +//usage: "\n l Long output" +//usage: ) +//usage: IF_FEATURE_SHOW_THREADS( +//usage: "\n T Show threads" +//usage: ) //usage: //usage:#endif /* ENABLE_DESKTOP */ //usage: @@ -56,15 +62,15 @@ //usage: " 2990 andersen andersen R ps\n" #include "libbb.h" +#ifdef __linux__ +# include <sys/sysinfo.h> +#endif /* Absolute maximum on output line length */ enum { MAX_WIDTH = 2*1024 }; #if ENABLE_DESKTOP -#ifdef __linux__ -# include <sys/sysinfo.h> -#endif #include <sys/times.h> /* for times() */ #ifndef AT_CLKTCK # define AT_CLKTCK 17 @@ -625,15 +631,21 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) enum { OPT_Z = (1 << 0) * ENABLE_SELINUX, OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS, + OPT_l = (1 << ENABLE_SELINUX) * (1 << ENABLE_FEATURE_SHOW_THREADS) * ENABLE_FEATURE_PS_LONG, }; +#if ENABLE_FEATURE_PS_LONG + time_t now = now; + struct sysinfo info; +#endif int opts = 0; /* If we support any options, parse argv */ -#if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE +#if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE || ENABLE_FEATURE_PS_LONG # if ENABLE_FEATURE_PS_WIDE /* -w is a bit complicated */ int w_count = 0; opt_complementary = "-:ww"; - opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")"w", &w_count); + opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l") + "w", &w_count); /* if w is given once, GNU ps sets the width to 132, * if w is given more than once, it is "unlimited" */ @@ -648,23 +660,47 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) # else /* -w is not supported, only -Z and/or -T */ opt_complementary = "-"; - opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")); + opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")); # endif -#endif -#if ENABLE_SELINUX +# if ENABLE_SELINUX if ((opts & OPT_Z) && is_selinux_enabled()) { psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT | PSSCAN_STATE | PSSCAN_COMM; puts(" PID CONTEXT STAT COMMAND"); } else -#endif - { +# endif + if (opts & OPT_l) { + psscan_flags = PSSCAN_STATE | PSSCAN_UIDGID | PSSCAN_PID | PSSCAN_PPID + | PSSCAN_TTY | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_COMM + | PSSCAN_VSZ | PSSCAN_RSS; +/* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html + * mandates for -l: + * -F Flags associated with the process (?) + * S The state of the process + * UID,PID,PPID + * -C Processor utilization for scheduling + * -PRI The priority of the process; higher numbers mean lower priority + * -NI Nice value; used in priority computation + * -ADDR The address of the process + * SZ The size in blocks of the core image of the process + * -WCHAN The event for which the process is waiting or sleeping + * TTY + * TIME The cumulative execution time for the process + * CMD + * We don't show fileds marked with '-'. We show VSZ and RSS instead of SZ + */ + puts("S UID PID PPID VSZ RSS TTY TIME CMD"); + now = time(NULL); + sysinfo(&info); + } + else { puts(" PID USER VSZ STAT COMMAND"); } if (opts & OPT_T) { psscan_flags |= PSSCAN_TASKS; } +#endif p = NULL; while ((p = procps_scan(p, psscan_flags)) != NULL) { @@ -678,15 +714,46 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) } else #endif { - const char *user = get_cached_username(p->uid); - //if (p->vsz == 0) - // len = printf("%5u %-8.8s %s ", - // p->pid, user, p->state); - //else + char buf6[6]; + smart_ulltoa5(p->vsz, buf6, " mgtpezy"); + buf6[5] = '\0'; +#if ENABLE_FEATURE_PS_LONG + if (opts & OPT_l) { + char bufr[6], strt[6]; + char tty[2 * sizeof(int)*3 + 2]; + char *endp; + unsigned sut = (p->stime + p->utime) / 100; + unsigned elapsed = info.uptime - (p->start_time / 100); + time_t start = now - elapsed; + struct tm *tm = localtime(&start); + + smart_ulltoa5(p->rss, bufr, " mgtpezy"); + bufr[5] = '\0'; + + if (p->tty_major == 136) + endp = stpcpy(tty, "pts/"); + else + if (p->tty_major == 4) { + endp = stpcpy(tty, "tty"); + if (p->tty_minor >= 64) { + p->tty_minor -= 64; + *endp++ = 'S'; + } + } + else + endp = tty + sprintf(tty, "%d:", p->tty_major); + strcpy(endp, utoa(p->tty_minor)); + + strftime(strt, 6, (elapsed >= (24 * 60 * 60)) ? "%b%d" : "%H:%M", tm); + strt[5] = '\0'; + // S UID PID PPID VSZ RSS TTY TIME CMD + len = printf("%c %5u %5u %5u %5s %5s %-5s %02u:%02u:%02u ", + p->state[0], p->uid, p->pid, p->ppid, buf6, bufr, tty, + sut / 3600, (sut % 3600) / 60, sut % 60); + } else +#endif { - char buf6[6]; - smart_ulltoa5(p->vsz, buf6, " mgtpezy"); - buf6[5] = '\0'; + const char *user = get_cached_username(p->uid); len = printf("%5u %-8.8s %s %s ", p->pid, user, buf6, p->state); } |