aboutsummaryrefslogtreecommitdiff
path: root/procps/ps.c
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/ps.c
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/ps.c')
-rw-r--r--procps/ps.c108
1 files changed, 91 insertions, 17 deletions
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 }