Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/procps/ps.c


Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

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

    r1765 r2725  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 * Fix for SELinux Support:(c)2007 Hiroshi Shinji <shiroshi@my.email.ne.jp>
    7                            (c)2007 Yuichi Nakamura <ynakam@hitachisoft.jp>
     7 *                         (c)2007 Yuichi Nakamura <ynakam@hitachisoft.jp>
    88 *
    9  * Licensed under the GPL version 2, see the file LICENSE in this tarball.
     9 * Licensed under GPLv2, see file LICENSE in this source tree.
    1010 */
    1111
     
    1717#if ENABLE_DESKTOP
    1818
    19 /* Print value to buf, max size+1 chars (including trailing '\0') */
    20 
    21 static void func_user(char *buf, int size, const procps_status_t *ps)
    22 {
    23     safe_strncpy(buf, get_cached_username(ps->uid), size+1);
    24 }
    25 
    26 static void func_comm(char *buf, int size, const procps_status_t *ps)
    27 {
    28     safe_strncpy(buf, ps->comm, size+1);
    29 }
    30 
    31 static void func_args(char *buf, int size, const procps_status_t *ps)
    32 {
    33     read_cmdline(buf, size, ps->pid, ps->comm);
    34 }
    35 
    36 static void func_pid(char *buf, int size, const procps_status_t *ps)
    37 {
    38     sprintf(buf, "%*u", size, ps->pid);
    39 }
    40 
    41 static void func_ppid(char *buf, int size, const procps_status_t *ps)
    42 {
    43     sprintf(buf, "%*u", size, ps->ppid);
    44 }
    45 
    46 static void func_pgid(char *buf, int size, const procps_status_t *ps)
    47 {
    48     sprintf(buf, "%*u", size, ps->pgid);
    49 }
    50 
    51 static void put_u(char *buf, int size, unsigned u)
    52 {
    53     char buf5[5];
    54     smart_ulltoa5( ((unsigned long long)u) << 10, buf5);
    55     sprintf(buf, "%.*s", size, buf5);
    56 }
    57 
    58 static void func_vsz(char *buf, int size, const procps_status_t *ps)
    59 {
    60     put_u(buf, size, ps->vsz);
    61 }
    62 
    63 static void func_rss(char *buf, int size, const procps_status_t *ps)
    64 {
    65     put_u(buf, size, ps->rss);
    66 }
    67 
    68 static void func_tty(char *buf, int size, const procps_status_t *ps)
    69 {
    70     buf[0] = '?';
    71     buf[1] = '\0';
    72     if (ps->tty_major) /* tty field of "0" means "no tty" */
    73         snprintf(buf, size+1, "%u,%u", ps->tty_major, ps->tty_minor);
    74 }
     19#include <sys/times.h> /* for times() */
     20#ifndef AT_CLKTCK
     21#define AT_CLKTCK 17
     22#endif
     23
    7524
    7625#if ENABLE_SELINUX
    77 static void func_label(char *buf, int size, const procps_status_t *ps)
    78 {
    79     safe_strncpy(buf, ps->context ? ps->context : "unknown", size+1);
    80 }
    81 #endif
    82 
    83 /*
    84 static void func_nice(char *buf, int size, const procps_status_t *ps)
    85 {
    86     ps->???
    87 }
    88 
    89 static void func_etime(char *buf, int size, const procps_status_t *ps)
    90 {
    91     elapled time [[dd-]hh:]mm:ss
    92 }
    93 
    94 static void func_time(char *buf, int size, const procps_status_t *ps)
    95 {
    96     cumulative time [[dd-]hh:]mm:ss
    97 }
    98 
    99 static void func_pcpu(char *buf, int size, const procps_status_t *ps)
    100 {
    101 }
    102 */
     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
    10331
    10432typedef struct {
    10533    uint16_t width;
    106     char name[6];
     34    char name6[6];
    10735    const char *header;
    10836    void (*f)(char *buf, int size, const procps_status_t *ps);
    10937    int ps_flags;
    11038} ps_out_t;
    111 
    112 static const ps_out_t out_spec[] = {
    113 // Mandated by POSIX:
    114     { 8                  , "user"  ,"USER"   ,func_user  ,PSSCAN_UIDGID  },
    115     { 16                 , "comm"  ,"COMMAND",func_comm  ,PSSCAN_COMM    },
    116     { 256                , "args"  ,"COMMAND",func_args  ,PSSCAN_COMM    },
    117     { 5                  , "pid"   ,"PID"    ,func_pid   ,PSSCAN_PID     },
    118     { 5                  , "ppid"  ,"PPID"   ,func_ppid  ,PSSCAN_PPID    },
    119     { 5                  , "pgid"  ,"PGID"   ,func_pgid  ,PSSCAN_PGID    },
    120 //  { sizeof("ELAPSED")-1, "etime" ,"ELAPSED",func_etime ,PSSCAN_        },
    121 //  { sizeof("GROUP"  )-1, "group" ,"GROUP"  ,func_group ,PSSCAN_UIDGID  },
    122 //  { sizeof("NI"     )-1, "nice"  ,"NI"     ,func_nice  ,PSSCAN_        },
    123 //  { sizeof("%CPU"   )-1, "pcpu"  ,"%CPU"   ,func_pcpu  ,PSSCAN_        },
    124 //  { sizeof("RGROUP" )-1, "rgroup","RGROUP" ,func_rgroup,PSSCAN_UIDGID  },
    125 //  { sizeof("RUSER"  )-1, "ruser" ,"RUSER"  ,func_ruser ,PSSCAN_UIDGID  },
    126 //  { sizeof("TIME"   )-1, "time"  ,"TIME"   ,func_time  ,PSSCAN_        },
    127     { 6                  , "tty"   ,"TT"     ,func_tty   ,PSSCAN_TTY     },
    128     { 4                  , "vsz"   ,"VSZ"    ,func_vsz   ,PSSCAN_VSZ     },
    129 // Not mandated by POSIX, but useful:
    130     { 4                  , "rss"   ,"RSS"    ,func_rss   ,PSSCAN_RSS     },
    131 #if ENABLE_SELINUX
    132     { 35                 , "label" ,"LABEL"  ,func_label ,PSSCAN_CONTEXT },
    133 #endif
    134 };
    135 
    136 #if ENABLE_SELINUX
    137 #define SELINIX_O_PREFIX "label,"
    138 #define DEFAULT_O_STR    SELINIX_O_PREFIX "pid,user" /* TODO: ,vsz,stat */ ",args"
    139 #else
    140 #define DEFAULT_O_STR    "pid,user" /* TODO: ,vsz,stat */ ",args"
    141 #endif
    14239
    14340struct globals {
     
    14845    char *buffer;
    14946    unsigned terminal_width;
     47#if ENABLE_FEATURE_PS_TIME
     48    unsigned kernel_HZ;
     49    unsigned long long seconds_since_boot;
     50#endif
    15051    char default_o[sizeof(DEFAULT_O_STR)];
     52} FIX_ALIASING;
     53#define G (*(struct globals*)&bb_common_bufsiz1)
     54#define out                (G.out               )
     55#define out_cnt            (G.out_cnt           )
     56#define print_header       (G.print_header      )
     57#define need_flags         (G.need_flags        )
     58#define buffer             (G.buffer            )
     59#define terminal_width     (G.terminal_width    )
     60#define kernel_HZ          (G.kernel_HZ         )
     61#define seconds_since_boot (G.seconds_since_boot)
     62#define default_o          (G.default_o         )
     63#define INIT_G() do { } while (0)
     64
     65#if ENABLE_FEATURE_PS_TIME
     66/* for ELF executables, notes are pushed before environment and args */
     67static ptrdiff_t find_elf_note(ptrdiff_t findme)
     68{
     69    ptrdiff_t *ep = (ptrdiff_t *) environ;
     70
     71    while (*ep++);
     72    while (*ep) {
     73        if (ep[0] == findme) {
     74            return ep[1];
     75        }
     76        ep += 2;
     77    }
     78    return -1;
     79}
     80
     81#if ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS
     82static unsigned get_HZ_by_waiting(void)
     83{
     84    struct timeval tv1, tv2;
     85    unsigned t1, t2, r, hz;
     86    unsigned cnt = cnt; /* for compiler */
     87    int diff;
     88
     89    r = 0;
     90
     91    /* Wait for times() to reach new tick */
     92    t1 = times(NULL);
     93    do {
     94        t2 = times(NULL);
     95    } while (t2 == t1);
     96    gettimeofday(&tv2, NULL);
     97
     98    do {
     99        t1 = t2;
     100        tv1.tv_usec = tv2.tv_usec;
     101
     102        /* Wait exactly one times() tick */
     103        do {
     104            t2 = times(NULL);
     105        } while (t2 == t1);
     106        gettimeofday(&tv2, NULL);
     107
     108        /* Calculate ticks per sec, rounding up to even */
     109        diff = tv2.tv_usec - tv1.tv_usec;
     110        if (diff <= 0) diff += 1000000;
     111        hz = 1000000u / (unsigned)diff;
     112        hz = (hz+1) & ~1;
     113
     114        /* Count how many same hz values we saw */
     115        if (r != hz) {
     116            r = hz;
     117            cnt = 0;
     118        }
     119        cnt++;
     120    } while (cnt < 3); /* exit if saw 3 same values */
     121
     122    return r;
     123}
     124#else
     125static inline unsigned get_HZ_by_waiting(void)
     126{
     127    /* Better method? */
     128    return 100;
     129}
     130#endif
     131
     132static unsigned get_kernel_HZ(void)
     133{
     134    //char buf[64];
     135    struct sysinfo info;
     136
     137    if (kernel_HZ)
     138        return kernel_HZ;
     139
     140    /* Works for ELF only, Linux 2.4.0+ */
     141    kernel_HZ = find_elf_note(AT_CLKTCK);
     142    if (kernel_HZ == (unsigned)-1)
     143        kernel_HZ = get_HZ_by_waiting();
     144
     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;
     151
     152    return kernel_HZ;
     153}
     154#endif
     155
     156/* Print value to buf, max size+1 chars (including trailing '\0') */
     157
     158static void func_user(char *buf, int size, const procps_status_t *ps)
     159{
     160#if 1
     161    safe_strncpy(buf, get_cached_username(ps->uid), size+1);
     162#else
     163    /* "compatible" version, but it's larger */
     164    /* procps 2.18 shows numeric UID if name overflows the field */
     165    /* TODO: get_cached_username() returns numeric string if
     166     * user has no passwd record, we will display it
     167     * left-justified here; too long usernames are shown
     168     * as _right-justified_ IDs. Is it worth fixing? */
     169    const char *user = get_cached_username(ps->uid);
     170    if (strlen(user) <= size)
     171        safe_strncpy(buf, user, size+1);
     172    else
     173        sprintf(buf, "%*u", size, (unsigned)ps->uid);
     174#endif
     175}
     176
     177static void func_group(char *buf, int size, const procps_status_t *ps)
     178{
     179    safe_strncpy(buf, get_cached_groupname(ps->gid), size+1);
     180}
     181
     182static void func_comm(char *buf, int size, const procps_status_t *ps)
     183{
     184    safe_strncpy(buf, ps->comm, size+1);
     185}
     186
     187static void func_args(char *buf, int size, const procps_status_t *ps)
     188{
     189    read_cmdline(buf, size+1, ps->pid, ps->comm);
     190}
     191
     192static void func_pid(char *buf, int size, const procps_status_t *ps)
     193{
     194    sprintf(buf, "%*u", size, ps->pid);
     195}
     196
     197static void func_ppid(char *buf, int size, const procps_status_t *ps)
     198{
     199    sprintf(buf, "%*u", size, ps->ppid);
     200}
     201
     202static void func_pgid(char *buf, int size, const procps_status_t *ps)
     203{
     204    sprintf(buf, "%*u", size, ps->pgid);
     205}
     206
     207static void put_lu(char *buf, int size, unsigned long u)
     208{
     209    char buf4[5];
     210
     211    /* see http://en.wikipedia.org/wiki/Tera */
     212    smart_ulltoa4(u, buf4, " mgtpezy");
     213    buf4[4] = '\0';
     214    sprintf(buf, "%.*s", size, buf4);
     215}
     216
     217static void func_vsz(char *buf, int size, const procps_status_t *ps)
     218{
     219    put_lu(buf, size, ps->vsz);
     220}
     221
     222static void func_rss(char *buf, int size, const procps_status_t *ps)
     223{
     224    put_lu(buf, size, ps->rss);
     225}
     226
     227static void func_tty(char *buf, int size, const procps_status_t *ps)
     228{
     229    buf[0] = '?';
     230    buf[1] = '\0';
     231    if (ps->tty_major) /* tty field of "0" means "no tty" */
     232        snprintf(buf, size+1, "%u,%u", ps->tty_major, ps->tty_minor);
     233}
     234
     235#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
     236
     237static void func_rgroup(char *buf, int size, const procps_status_t *ps)
     238{
     239    safe_strncpy(buf, get_cached_groupname(ps->rgid), size+1);
     240}
     241
     242static void func_ruser(char *buf, int size, const procps_status_t *ps)
     243{
     244    safe_strncpy(buf, get_cached_username(ps->ruid), size+1);
     245}
     246
     247static void func_nice(char *buf, int size, const procps_status_t *ps)
     248{
     249    sprintf(buf, "%*d", size, ps->niceness);
     250}
     251
     252#endif
     253
     254#if ENABLE_FEATURE_PS_TIME
     255
     256static void func_etime(char *buf, int size, const procps_status_t *ps)
     257{
     258    /* elapsed time [[dd-]hh:]mm:ss; here only mm:ss */
     259    unsigned long mm;
     260    unsigned ss;
     261
     262    mm = ps->start_time / get_kernel_HZ();
     263    /* must be after get_kernel_HZ()! */
     264    mm = seconds_since_boot - mm;
     265    ss = mm % 60;
     266    mm /= 60;
     267    snprintf(buf, size+1, "%3lu:%02u", mm, ss);
     268}
     269
     270static void func_time(char *buf, int size, const procps_status_t *ps)
     271{
     272    /* cumulative time [[dd-]hh:]mm:ss; here only mm:ss */
     273    unsigned long mm;
     274    unsigned ss;
     275
     276    mm = (ps->utime + ps->stime) / get_kernel_HZ();
     277    ss = mm % 60;
     278    mm /= 60;
     279    snprintf(buf, size+1, "%3lu:%02u", mm, ss);
     280}
     281
     282#endif
     283
     284#if ENABLE_SELINUX
     285static void func_label(char *buf, int size, const procps_status_t *ps)
     286{
     287    safe_strncpy(buf, ps->context ? ps->context : "unknown", size+1);
     288}
     289#endif
     290
     291/*
     292static void func_nice(char *buf, int size, const procps_status_t *ps)
     293{
     294    ps->???
     295}
     296
     297static void func_pcpu(char *buf, int size, const procps_status_t *ps)
     298{
     299}
     300*/
     301
     302static const ps_out_t out_spec[] = {
     303// Mandated by POSIX:
     304    { 8                  , "user"  ,"USER"   ,func_user  ,PSSCAN_UIDGID  },
     305    { 8                  , "group" ,"GROUP"  ,func_group ,PSSCAN_UIDGID  },
     306    { 16                 , "comm"  ,"COMMAND",func_comm  ,PSSCAN_COMM    },
     307    { MAX_WIDTH          , "args"  ,"COMMAND",func_args  ,PSSCAN_COMM    },
     308    { 5                  , "pid"   ,"PID"    ,func_pid   ,PSSCAN_PID     },
     309    { 5                  , "ppid"  ,"PPID"   ,func_ppid  ,PSSCAN_PPID    },
     310    { 5                  , "pgid"  ,"PGID"   ,func_pgid  ,PSSCAN_PGID    },
     311#if ENABLE_FEATURE_PS_TIME
     312    { sizeof("ELAPSED")-1, "etime" ,"ELAPSED",func_etime ,PSSCAN_START_TIME },
     313#endif
     314#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
     315    { 5                  , "nice"  ,"NI"     ,func_nice  ,PSSCAN_NICE    },
     316    { 8                  , "rgroup","RGROUP" ,func_rgroup,PSSCAN_RUIDGID },
     317    { 8                  , "ruser" ,"RUSER"  ,func_ruser ,PSSCAN_RUIDGID },
     318//  { 5                  , "pcpu"  ,"%CPU"   ,func_pcpu  ,PSSCAN_        },
     319#endif
     320#if ENABLE_FEATURE_PS_TIME
     321    { 6                  , "time"  ,"TIME"   ,func_time  ,PSSCAN_STIME | PSSCAN_UTIME },
     322#endif
     323    { 6                  , "tty"   ,"TT"     ,func_tty   ,PSSCAN_TTY     },
     324    { 4                  , "vsz"   ,"VSZ"    ,func_vsz   ,PSSCAN_VSZ     },
     325// Not mandated by POSIX, but useful:
     326    { 4                  , "rss"   ,"RSS"    ,func_rss   ,PSSCAN_RSS     },
     327#if ENABLE_SELINUX
     328    { 35                 , "label" ,"LABEL"  ,func_label ,PSSCAN_CONTEXT },
     329#endif
    151330};
    152 #define G (*(struct globals*)&bb_common_bufsiz1)
    153 #define out            (G.out           )
    154 #define out_cnt        (G.out_cnt       )
    155 #define print_header   (G.print_header  )
    156 #define need_flags     (G.need_flags    )
    157 #define buffer         (G.buffer        )
    158 #define terminal_width (G.terminal_width)
    159 #define default_o      (G.default_o     )
    160331
    161332static ps_out_t* new_out_t(void)
    162333{
    163     int i = out_cnt++;
    164     out = xrealloc(out, out_cnt * sizeof(*out));
    165     return &out[i];
     334    out = xrealloc_vector(out, 2, out_cnt);
     335    return &out[out_cnt++];
    166336}
    167337
    168338static const ps_out_t* find_out_spec(const char *name)
    169339{
    170     int i;
     340    unsigned i;
     341    char buf[ARRAY_SIZE(out_spec)*7 + 1];
     342    char *p = buf;
     343
    171344    for (i = 0; i < ARRAY_SIZE(out_spec); i++) {
    172         if (!strcmp(name, out_spec[i].name))
     345        if (strncmp(name, out_spec[i].name6, 6) == 0)
    173346            return &out_spec[i];
    174     }
    175     bb_error_msg_and_die("bad -o argument '%s'", name);
     347        p += sprintf(p, "%.6s,", out_spec[i].name6);
     348    }
     349    p[-1] = '\0';
     350    bb_error_msg_and_die("bad -o argument '%s', supported arguments: %s", name, buf);
    176351}
    177352
     
    215390}
    216391
    217 static void post_process(void)
     392static void alloc_line_buffer(void)
    218393{
    219394    int i;
     
    225400        }
    226401        width += out[i].width + 1; /* "FIELD " */
     402        if ((int)(width - terminal_width) > 0) {
     403            /* The rest does not fit on the screen */
     404            //out[i].width -= (width - terminal_width - 1);
     405            out_cnt = i + 1;
     406            break;
     407        }
    227408    }
    228409#if ENABLE_SELINUX
     
    279460}
    280461
    281 int ps_main(int argc, char **argv);
    282 int ps_main(int argc, char **argv)
     462int ps_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     463int ps_main(int argc UNUSED_PARAM, char **argv)
    283464{
    284465    procps_status_t *p;
    285466    llist_t* opt_o = NULL;
    286     USE_SELINUX(int opt;)
     467    int opt;
     468    enum {
     469        OPT_Z = (1 << 0),
     470        OPT_o = (1 << 1),
     471        OPT_a = (1 << 2),
     472        OPT_A = (1 << 3),
     473        OPT_d = (1 << 4),
     474        OPT_e = (1 << 5),
     475        OPT_f = (1 << 6),
     476        OPT_l = (1 << 7),
     477        OPT_T = (1 << 8) * ENABLE_FEATURE_SHOW_THREADS,
     478    };
     479
     480    INIT_G();
    287481
    288482    // POSIX:
     
    291485    // -A  Write information for all processes
    292486    // -d  Write information for all processes, except session leaders
    293     // -e  Write information for all processes (equivalent to -A.)
     487    // -e  Write information for all processes (equivalent to -A)
    294488    // -f  Generate a full listing
    295489    // -l  Generate a long listing
    296490    // -o col1,col2,col3=header
    297491    //     Select which columns to display
    298     /* We allow (and ignore) most of the above. FIXME */
     492    /* We allow (and ignore) most of the above. FIXME.
     493     * -T is picked for threads (POSIX hasn't it standardized).
     494     * procps v3.2.7 supports -T and shows tids as SPID column,
     495     * it also supports -L where it shows tids as LWP column.
     496     */
    299497    opt_complementary = "o::";
    300     USE_SELINUX(opt =) getopt32(argv, "Zo:aAdefl", &opt_o);
     498    opt = getopt32(argv, "Zo:aAdefl"IF_FEATURE_SHOW_THREADS("T"), &opt_o);
    301499    if (opt_o) {
    302500        do {
    303             parse_o(opt_o->data);
    304             opt_o = opt_o->link;
     501            parse_o(llist_pop(&opt_o));
    305502        } while (opt_o);
    306503    } else {
    307504        /* Below: parse_o() needs char*, NOT const char*... */
    308505#if ENABLE_SELINUX
    309         if (!(opt & 1) || !is_selinux_enabled()) {
     506        if (!(opt & OPT_Z) || !is_selinux_enabled()) {
    310507            /* no -Z or no SELinux: do not show LABEL */
    311             strcpy(default_o, DEFAULT_O_STR + sizeof(SELINIX_O_PREFIX)-1);
     508            strcpy(default_o, DEFAULT_O_STR + sizeof(SELINUX_O_PREFIX)-1);
    312509        } else
    313510#endif
     
    317514        parse_o(default_o);
    318515    }
    319     post_process();
     516#if ENABLE_FEATURE_SHOW_THREADS
     517    if (opt & OPT_T)
     518        need_flags |= PSSCAN_TASKS;
     519#endif
    320520
    321521    /* Was INT_MAX, but some libc's go belly up with printf("%.*s")
     
    327527            terminal_width = MAX_WIDTH;
    328528    }
     529    alloc_line_buffer();
    329530    format_header();
    330531
    331532    p = NULL;
    332     while ((p = procps_scan(p, need_flags))) {
     533    while ((p = procps_scan(p, need_flags)) != NULL) {
    333534        format_process(p);
    334535    }
     
    341542
    342543
    343 int ps_main(int argc, char **argv);
    344 int ps_main(int argc, char **argv)
    345 {
    346     procps_status_t *p = NULL;
    347     int len;
    348     SKIP_SELINUX(const) int use_selinux = 0;
    349     USE_SELINUX(int i;)
    350 #if !ENABLE_FEATURE_PS_WIDE
    351     enum { terminal_width = 79 };
    352 #else
    353     int terminal_width;
     544int ps_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     545int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
     546{
     547    procps_status_t *p;
     548    int psscan_flags = PSSCAN_PID | PSSCAN_UIDGID
     549            | PSSCAN_STATE | PSSCAN_VSZ | PSSCAN_COMM;
     550    unsigned terminal_width IF_NOT_FEATURE_PS_WIDE(= 79);
     551    enum {
     552        OPT_Z = (1 << 0) * ENABLE_SELINUX,
     553        OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS,
     554    };
     555    int opts = 0;
     556    /* If we support any options, parse argv */
     557#if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE
     558# if ENABLE_FEATURE_PS_WIDE
     559    /* -w is a bit complicated */
    354560    int w_count = 0;
    355 #endif
    356 
    357 #if ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX
    358 #if ENABLE_FEATURE_PS_WIDE
    359561    opt_complementary = "-:ww";
    360     USE_SELINUX(i =) getopt32(argv, USE_SELINUX("Z") "w", &w_count);
     562    opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")"w", &w_count);
    361563    /* if w is given once, GNU ps sets the width to 132,
    362564     * if w is given more than once, it is "unlimited"
    363565     */
    364566    if (w_count) {
    365         terminal_width = (w_count==1) ? 132 : MAX_WIDTH;
     567        terminal_width = (w_count == 1) ? 132 : MAX_WIDTH;
    366568    } else {
    367569        get_terminal_width_height(0, &terminal_width, NULL);
     
    370572            terminal_width = MAX_WIDTH;
    371573    }
    372 #else /* only ENABLE_SELINUX */
    373     i = getopt32(argv, "Z");
    374 #endif
     574# else
     575    /* -w is not supported, only -Z and/or -T */
     576    opt_complementary = "-";
     577    opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T"));
     578# endif
     579#endif
     580
    375581#if ENABLE_SELINUX
    376     if ((i & 1) && is_selinux_enabled())
    377         use_selinux = PSSCAN_CONTEXT;
    378 #endif
    379 #endif /* ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX */
    380 
    381     if (use_selinux)
    382         puts("  PID Context                          Stat Command");
    383     else
    384         puts("  PID  Uid        VSZ Stat Command");
    385 
    386     while ((p = procps_scan(p, 0
    387             | PSSCAN_PID
    388             | PSSCAN_UIDGID
    389             | PSSCAN_STATE
    390             | PSSCAN_VSZ
    391             | PSSCAN_COMM
    392             | use_selinux
    393     ))) {
     582    if ((opts & OPT_Z) && is_selinux_enabled()) {
     583        psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT
     584                | PSSCAN_STATE | PSSCAN_COMM;
     585        puts("  PID CONTEXT                          STAT COMMAND");
     586    } else
     587#endif
     588    {
     589        puts("  PID USER       VSZ STAT COMMAND");
     590    }
     591    if (opts & OPT_T) {
     592        psscan_flags |= PSSCAN_TASKS;
     593    }
     594
     595    p = NULL;
     596    while ((p = procps_scan(p, psscan_flags)) != NULL) {
     597        int len;
    394598#if ENABLE_SELINUX
    395         if (use_selinux) {
    396             len = printf("%5u %-32s %s ",
     599        if (psscan_flags & PSSCAN_CONTEXT) {
     600            len = printf("%5u %-32.32s %s ",
    397601                    p->pid,
    398602                    p->context ? p->context : "unknown",
     
    402606        {
    403607            const char *user = get_cached_username(p->uid);
    404             if (p->vsz == 0)
    405                 len = printf("%5u %-8s        %s ",
    406                     p->pid, user, p->state);
    407             else
    408                 len = printf("%5u %-8s %6u %s ",
    409                     p->pid, user, p->vsz, p->state);
     608            //if (p->vsz == 0)
     609            //  len = printf("%5u %-8.8s        %s ",
     610            //      p->pid, user, p->state);
     611            //else
     612            {
     613                char buf6[6];
     614                smart_ulltoa5(p->vsz, buf6, " mgtpezy");
     615                buf6[5] = '\0';
     616                len = printf("%5u %-8.8s %s %s  ",
     617                    p->pid, user, buf6, p->state);
     618            }
    410619        }
    411620
     
    422631}
    423632
    424 #endif /* ENABLE_DESKTOP */
     633#endif /* !ENABLE_DESKTOP */
Note: See TracChangeset for help on using the changeset viewer.