Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/procps/ps.c


Ignore:
Timestamp:
Jan 1, 2014, 12:47:38 AM (10 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.21.1
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.2/mindi-busybox/procps/ps.c

    r2725 r3232  
    1010 */
    1111
     12//usage:#if ENABLE_DESKTOP
     13//usage:
     14//usage:#define ps_trivial_usage
     15//usage:       "[-o COL1,COL2=HEADER]" IF_FEATURE_SHOW_THREADS(" [-T]")
     16//usage:#define ps_full_usage "\n\n"
     17//usage:       "Show list of processes\n"
     18//usage:     "\n    -o COL1,COL2=HEADER Select columns for display"
     19//usage:    IF_FEATURE_SHOW_THREADS(
     20//usage:     "\n    -T          Show threads"
     21//usage:    )
     22//usage:
     23//usage:#else /* !ENABLE_DESKTOP */
     24//usage:
     25//usage:#if !ENABLE_SELINUX && !ENABLE_FEATURE_PS_WIDE
     26//usage:#define USAGE_PS "\nThis version of ps accepts no options"
     27//usage:#else
     28//usage:#define USAGE_PS ""
     29//usage:#endif
     30//usage:
     31//usage:#define ps_trivial_usage
     32//usage:       ""
     33//usage:#define ps_full_usage "\n\n"
     34//usage:       "Show list of processes\n"
     35//usage:    USAGE_PS
     36//usage:    IF_SELINUX(
     37//usage:     "\n    -Z  Show selinux context"
     38//usage:    )
     39//usage:    IF_FEATURE_PS_WIDE(
     40//usage:     "\n    w   Wide output"
     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:    )
     48//usage:
     49//usage:#endif /* ENABLE_DESKTOP */
     50//usage:
     51//usage:#define ps_example_usage
     52//usage:       "$ ps\n"
     53//usage:       "  PID  Uid      Gid State Command\n"
     54//usage:       "    1 root     root     S init\n"
     55//usage:       "    2 root     root     S [kflushd]\n"
     56//usage:       "    3 root     root     S [kupdate]\n"
     57//usage:       "    4 root     root     S [kpiod]\n"
     58//usage:       "    5 root     root     S [kswapd]\n"
     59//usage:       "  742 andersen andersen S [bash]\n"
     60//usage:       "  743 andersen andersen S -bash\n"
     61//usage:       "  745 root     root     S [getty]\n"
     62//usage:       " 2990 andersen andersen R ps\n"
     63
    1264#include "libbb.h"
     65#ifdef __linux__
     66# include <sys/sysinfo.h>
     67#endif
    1368
    1469/* Absolute maximum on output line length */
    1570enum { MAX_WIDTH = 2*1024 };
    1671
     72#if ENABLE_FEATURE_PS_TIME || ENABLE_FEATURE_PS_LONG
     73static long get_uptime(void)
     74{
     75#ifdef __linux__
     76    struct sysinfo info;
     77    if (sysinfo(&info) < 0)
     78        return 0;
     79    return info.uptime;
     80#elif 1
     81    char buf[64];
     82    long uptime;
     83    if (open_read_close("/proc/uptime", buf, sizeof(buf)) <= 0)
     84        bb_perror_msg_and_die("can't read %s", "/proc/uptime");
     85    buf[sizeof(buf)-1] = '\0';
     86    sscanf(buf, "%l", &uptime);
     87    return uptime;
     88#else
     89    struct timespec ts;
     90    if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0)
     91        return 0;
     92    return ts.tv_sec;
     93#endif
     94}
     95#endif
     96
    1797#if ENABLE_DESKTOP
    1898
    1999#include <sys/times.h> /* for times() */
    20100#ifndef AT_CLKTCK
    21 #define AT_CLKTCK 17
    22 #endif
    23 
    24 
    25 #if ENABLE_SELINUX
    26 #define SELINUX_O_PREFIX "label,"
    27 #define DEFAULT_O_STR    (SELINUX_O_PREFIX "pid,user" IF_FEATURE_PS_TIME(",time") ",args")
    28 #else
    29 #define DEFAULT_O_STR    ("pid,user" IF_FEATURE_PS_TIME(",time") ",args")
    30 #endif
    31 
     101# define AT_CLKTCK 17
     102#endif
     103
     104/* TODO:
     105 * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html
     106 * specifies (for XSI-conformant systems) following default columns
     107 * (l and f mark columns shown with -l and -f respectively):
     108 * F     l   Flags (octal and additive) associated with the process (??)
     109 * S     l   The state of the process
     110 * UID   f,l The user ID; the login name is printed with -f
     111 * PID       The process ID
     112 * PPID  f,l The parent process
     113 * C     f,l Processor utilization
     114 * PRI   l   The priority of the process; higher numbers mean lower priority
     115 * NI    l   Nice value
     116 * ADDR  l   The address of the process
     117 * SZ    l   The size in blocks of the core image of the process
     118 * WCHAN l   The event for which the process is waiting or sleeping
     119 * STIME f   Starting time of the process
     120 * TTY       The controlling terminal for the process
     121 * TIME      The cumulative execution time for the process
     122 * CMD       The command name; the full command line is shown with -f
     123 */
    32124typedef struct {
    33125    uint16_t width;
     
    49141    unsigned long long seconds_since_boot;
    50142#endif
    51     char default_o[sizeof(DEFAULT_O_STR)];
    52143} FIX_ALIASING;
    53144#define G (*(struct globals*)&bb_common_bufsiz1)
     
    60151#define kernel_HZ          (G.kernel_HZ         )
    61152#define seconds_since_boot (G.seconds_since_boot)
    62 #define default_o          (G.default_o         )
    63153#define INIT_G() do { } while (0)
    64154
     
    69159    ptrdiff_t *ep = (ptrdiff_t *) environ;
    70160
    71     while (*ep++);
     161    while (*ep++)
     162        continue;
    72163    while (*ep) {
    73164        if (ep[0] == findme) {
     
    132223static unsigned get_kernel_HZ(void)
    133224{
    134     //char buf[64];
    135     struct sysinfo info;
    136225
    137226    if (kernel_HZ)
     
    143232        kernel_HZ = get_HZ_by_waiting();
    144233
    145     //if (open_read_close("/proc/uptime", buf, sizeof(buf)) <= 0)
    146     //  bb_perror_msg_and_die("can't read %s", "/proc/uptime");
    147     //buf[sizeof(buf)-1] = '\0';
    148     ///sscanf(buf, "%llu", &seconds_since_boot);
    149     sysinfo(&info);
    150     seconds_since_boot = info.uptime;
     234    seconds_since_boot = get_uptime();
    151235
    152236    return kernel_HZ;
     
    185269}
    186270
     271static void func_state(char *buf, int size, const procps_status_t *ps)
     272{
     273    safe_strncpy(buf, ps->state, size+1);
     274}
     275
    187276static void func_args(char *buf, int size, const procps_status_t *ps)
    188277{
     
    301390
    302391static const ps_out_t out_spec[] = {
    303 // Mandated by POSIX:
     392/* Mandated by http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html: */
    304393    { 8                  , "user"  ,"USER"   ,func_user  ,PSSCAN_UIDGID  },
    305394    { 8                  , "group" ,"GROUP"  ,func_group ,PSSCAN_UIDGID  },
     
    323412    { 6                  , "tty"   ,"TT"     ,func_tty   ,PSSCAN_TTY     },
    324413    { 4                  , "vsz"   ,"VSZ"    ,func_vsz   ,PSSCAN_VSZ     },
    325 // Not mandated by POSIX, but useful:
     414/* Not mandated, but useful: */
     415    { 4                  , "stat"  ,"STAT"   ,func_state ,PSSCAN_STATE   },
    326416    { 4                  , "rss"   ,"RSS"    ,func_rss   ,PSSCAN_RSS     },
    327417#if ENABLE_SELINUX
     
    460550}
    461551
     552#if ENABLE_SELINUX
     553# define SELINUX_O_PREFIX "label,"
     554# define DEFAULT_O_STR    (SELINUX_O_PREFIX "pid,user" IF_FEATURE_PS_TIME(",time") ",args")
     555#else
     556# define DEFAULT_O_STR    ("pid,user" IF_FEATURE_PS_TIME(",time") ",args")
     557#endif
     558
    462559int ps_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    463560int ps_main(int argc UNUSED_PARAM, char **argv)
     
    465562    procps_status_t *p;
    466563    llist_t* opt_o = NULL;
     564    char default_o[sizeof(DEFAULT_O_STR)];
    467565    int opt;
    468566    enum {
     
    502600        } while (opt_o);
    503601    } else {
    504         /* Below: parse_o() needs char*, NOT const char*... */
     602        /* Below: parse_o() needs char*, NOT const char*, can't give it default_o */
    505603#if ENABLE_SELINUX
    506604        if (!(opt & OPT_Z) || !is_selinux_enabled()) {
     
    552650        OPT_Z = (1 << 0) * ENABLE_SELINUX,
    553651        OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS,
     652        OPT_l = (1 << ENABLE_SELINUX) * (1 << ENABLE_FEATURE_SHOW_THREADS) * ENABLE_FEATURE_PS_LONG,
    554653    };
     654#if ENABLE_FEATURE_PS_LONG
     655    time_t now = now;
     656    long uptime;
     657#endif
     658    /* If we support any options, parse argv */
     659#if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE || ENABLE_FEATURE_PS_LONG
    555660    int opts = 0;
    556     /* If we support any options, parse argv */
    557 #if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE
    558661# if ENABLE_FEATURE_PS_WIDE
    559662    /* -w is a bit complicated */
    560663    int w_count = 0;
    561664    opt_complementary = "-:ww";
    562     opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")"w", &w_count);
     665    opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")
     666                    "w", &w_count);
    563667    /* if w is given once, GNU ps sets the width to 132,
    564668     * if w is given more than once, it is "unlimited"
     
    575679    /* -w is not supported, only -Z and/or -T */
    576680    opt_complementary = "-";
    577     opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T"));
     681    opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l"));
    578682# endif
    579 #endif
    580 
    581 #if ENABLE_SELINUX
     683
     684# if ENABLE_SELINUX
    582685    if ((opts & OPT_Z) && is_selinux_enabled()) {
    583686        psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT
     
    585688        puts("  PID CONTEXT                          STAT COMMAND");
    586689    } else
    587 #endif
    588     {
     690# endif
     691    if (opts & OPT_l) {
     692        psscan_flags = PSSCAN_STATE | PSSCAN_UIDGID | PSSCAN_PID | PSSCAN_PPID
     693            | PSSCAN_TTY | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_COMM
     694            | PSSCAN_VSZ | PSSCAN_RSS;
     695/* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html
     696 * mandates for -l:
     697 * -F     Flags (?)
     698 * S      State
     699 * UID,PID,PPID
     700 * -C     CPU usage
     701 * -PRI   The priority of the process; higher numbers mean lower priority
     702 * -NI    Nice value
     703 * -ADDR  The address of the process (?)
     704 * SZ     The size in blocks of the core image
     705 * -WCHAN The event for which the process is waiting or sleeping
     706 * TTY
     707 * TIME   The cumulative execution time
     708 * CMD
     709 * We don't show fields marked with '-'.
     710 * We show VSZ and RSS instead of SZ.
     711 * We also show STIME (standard says that -f shows it, -l doesn't).
     712 */
     713        puts("S   UID   PID  PPID   VSZ   RSS TTY   STIME TIME     CMD");
     714# if ENABLE_FEATURE_PS_LONG
     715        now = time(NULL);
     716        uptime = get_uptime();
     717# endif
     718    }
     719    else {
    589720        puts("  PID USER       VSZ STAT COMMAND");
    590721    }
     
    592723        psscan_flags |= PSSCAN_TASKS;
    593724    }
     725#endif
    594726
    595727    p = NULL;
     
    605737#endif
    606738        {
    607             const char *user = get_cached_username(p->uid);
    608             //if (p->vsz == 0)
    609             //  len = printf("%5u %-8.8s        %s ",
    610             //      p->pid, user, p->state);
    611             //else
     739            char buf6[6];
     740            smart_ulltoa5(p->vsz, buf6, " mgtpezy");
     741            buf6[5] = '\0';
     742#if ENABLE_FEATURE_PS_LONG
     743            if (opts & OPT_l) {
     744                char bufr[6], stime_str[6];
     745                char tty[2 * sizeof(int)*3 + 2];
     746                char *endp;
     747                unsigned sut = (p->stime + p->utime) / 100;
     748                unsigned elapsed = uptime - (p->start_time / 100);
     749                time_t start = now - elapsed;
     750                struct tm *tm = localtime(&start);
     751
     752                smart_ulltoa5(p->rss, bufr, " mgtpezy");
     753                bufr[5] = '\0';
     754
     755                if (p->tty_major == 136)
     756                    /* It should be pts/N, not ptsN, but N > 9
     757                     * will overflow field width...
     758                     */
     759                    endp = stpcpy(tty, "pts");
     760                else
     761                if (p->tty_major == 4) {
     762                    endp = stpcpy(tty, "tty");
     763                    if (p->tty_minor >= 64) {
     764                        p->tty_minor -= 64;
     765                        *endp++ = 'S';
     766                    }
     767                }
     768                else
     769                    endp = tty + sprintf(tty, "%d:", p->tty_major);
     770                strcpy(endp, utoa(p->tty_minor));
     771
     772                strftime(stime_str, 6, (elapsed >= (24 * 60 * 60)) ? "%b%d" : "%H:%M", tm);
     773                stime_str[5] = '\0';
     774                //            S  UID PID PPID VSZ RSS TTY STIME TIME        CMD
     775                len = printf("%c %5u %5u %5u %5s %5s %-5s %s %02u:%02u:%02u ",
     776                    p->state[0], p->uid, p->pid, p->ppid, buf6, bufr, tty,
     777                    stime_str, sut / 3600, (sut % 3600) / 60, sut % 60);
     778            } else
     779#endif
    612780            {
    613                 char buf6[6];
    614                 smart_ulltoa5(p->vsz, buf6, " mgtpezy");
    615                 buf6[5] = '\0';
     781                const char *user = get_cached_username(p->uid);
    616782                len = printf("%5u %-8.8s %s %s  ",
    617783                    p->pid, user, buf6, p->state);
Note: See TracChangeset for help on using the changeset viewer.