aboutsummaryrefslogtreecommitdiff
path: root/procps/ps.c
diff options
context:
space:
mode:
Diffstat (limited to 'procps/ps.c')
-rw-r--r--procps/ps.c103
1 files changed, 85 insertions, 18 deletions
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 */
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
@@ -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 }