ps: add -o tty and -o rss support
authorDenis Vlasenko <vda.linux@googlemail.com>
Thu, 19 Apr 2007 14:46:14 +0000 (14:46 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Thu, 19 Apr 2007 14:46:14 +0000 (14:46 -0000)
   1373      14      24    1411     583 busybox.t1/procps/ps.o
   1462      14      24    1500     5dc busybox.t2/procps/ps.o

include/libbb.h
libbb/procps.c
procps/ps.c
shell/hush.c

index 77f1e0a445e72f68b9e256067c26a0b80a44d4ff..31ded7e9c5af9bfd0ed4f4c9e139310bd0bc5d87 100644 (file)
@@ -805,7 +805,7 @@ typedef struct {
        DIR *dir;
 /* Fields are set to 0/NULL if failed to determine (or not requested) */
        char *cmd;
-       unsigned long vsz;
+       unsigned vsz, rss; /* we round it to kbytes */
        unsigned long stime, utime;
        unsigned pid;
        unsigned ppid;
@@ -813,9 +813,10 @@ typedef struct {
        unsigned sid;
        unsigned uid;
        unsigned gid;
-       /* basename of executable file in call to exec(2), size from */
-       /* sizeof(task_struct.comm) in /usr/include/linux/sched.h */
        char state[4];
+       char tty_str[8]; /* "maj,min" or "?" */
+       /* basename of executable in exec(2), read from /proc/N/stat, */
+       /* size from sizeof(task_struct.comm) in /usr/include/linux/sched.h */
        char comm[COMM_LEN];
        /* user/group? - use passwd/group parsing functions */
 } procps_status_t;
@@ -829,12 +830,16 @@ enum {
        PSSCAN_CMD      = 1 << 6,
        PSSCAN_STATE    = 1 << 7,
        PSSCAN_VSZ      = 1 << 8,
-       PSSCAN_STIME    = 1 << 9,
-       PSSCAN_UTIME    = 1 << 10,
+       PSSCAN_RSS      = 1 << 9,
+       PSSCAN_STIME    = 1 << 10,
+       PSSCAN_UTIME    = 1 << 11,
+       PSSCAN_TTY      = 1 << 12,
        /* These are all retrieved from proc/NN/stat in one go: */
        PSSCAN_STAT     = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID
                        | PSSCAN_COMM | PSSCAN_STATE
-                       | PSSCAN_VSZ | PSSCAN_STIME | PSSCAN_UTIME,
+                       | PSSCAN_VSZ | PSSCAN_RSS
+                       | PSSCAN_STIME | PSSCAN_UTIME
+                       | PSSCAN_TTY,
 };
 procps_status_t* alloc_procps_scan(int flags);
 void free_procps_scan(procps_status_t* sp);
index c9dcfde0c0f4327248efd412aa72e859af136f19..053f7d225b2721f8cf34f66f59a619ced8713ef1 100644 (file)
@@ -144,6 +144,9 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags)
 
                if (flags & PSSCAN_STAT) {
                        char *cp;
+                       unsigned long vsz, rss;
+                       int tty;
+
                        /* see proc(5) for some details on this */
                        strcpy(filename_tail, "/stat");
                        n = read_to_buf(filename, buf);
@@ -158,33 +161,46 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags)
                        sscanf(buf, "%*s (%15c", sp->comm);
                        n = sscanf(cp+2,
                                "%c %u "               /* state, ppid */
-                               "%u %u %*s %*s "       /* pgid, sid, tty, tpgid */
+                               "%u %u %d %*s "        /* pgid, sid, tty, tpgid */
                                "%*s %*s %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
                                "%lu %lu "             /* utime, stime */
                                "%*s %*s %*s "         /* cutime, cstime, priority */
                                "%ld "                 /* nice */
                                "%*s %*s %*s "         /* timeout, it_real_value, start_time */
-                               "%lu ",                /* vsize */
+                               "%lu "                 /* vsize */
+                               "%lu "                 /* rss */
+                       /*      "%lu %lu %lu %lu %lu %lu " rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */
+                       /*      "%u %u %u %u "         signal, blocked, sigignore, sigcatch */
+                       /*      "%lu %lu %lu"          wchan, nswap, cnswap */
+                               ,
                                sp->state, &sp->ppid,
-                               &sp->pgid, &sp->sid,
+                               &sp->pgid, &sp->sid, &tty,
                                &sp->utime, &sp->stime,
                                &tasknice,
-                               &sp->vsz);
-                       if (n != 8)
+                               &vsz,
+                               &rss);
+                       if (n != 10)
                                break;
 
+                       sp->tty_str[0] = '?';
+                       /* sp->tty_str[1] = '\0'; - done by memset */
+                       if (tty >= 0) /* tty field of "-1" means "no tty" */
+                               snprintf(sp->tty_str, sizeof(sp->tty_str), "%u,%u",
+                                       (tty >> 8) & 0xfff, /* major */
+                                       (tty & 0xff) | ((tty >> 12) & 0xfff00));
                        if (sp->vsz == 0 && sp->state[0] != 'Z')
                                sp->state[1] = 'W';
                        else
                                sp->state[1] = ' ';
                        if (tasknice < 0)
                                sp->state[2] = '<';
-                       else if (tasknice > 0)
+                       else if (tasknice) /* > 0 */
                                sp->state[2] = 'N';
                        else
                                sp->state[2] = ' ';
 
-                       sp->vsz >>= 10; /* vsize is in bytes and we want kb */
+                       sp->vsz = vsz >> 10; /* vsize is in bytes and we want kb */
+                       sp->rss = rss >> 10;
                }
 
                if (flags & PSSCAN_CMD) {
index f8f5c1aa9ebb35d8ac720078369d01e126cf3292..0c9b71e0906b1b9f112b3ae3fe0bd8689592ec1b 100644 (file)
@@ -29,83 +29,90 @@ static void func_args(char *buf, int size, const procps_status_t *ps)
        if (ps->cmd)
                safe_strncpy(buf, ps->cmd, size+1);
        else if (size >= 2)
-               snprintf(buf, size+1, "[%.*s]", size-2, ps->comm);
+               sprintf(buf, "[%.*s]", size-2, ps->comm);
 }
 
 static void func_pid(char *buf, int size, const procps_status_t *ps)
 {
-       snprintf(buf, size+1, "%*u", size, ps->pid);
+       sprintf(buf, "%*u", size, ps->pid);
 }
 
 static void func_ppid(char *buf, int size, const procps_status_t *ps)
 {
-       snprintf(buf, size+1, "%*u", size, ps->ppid);
+       sprintf(buf, "%*u", size, ps->ppid);
 }
 
 static void func_pgid(char *buf, int size, const procps_status_t *ps)
 {
-       snprintf(buf, size+1, "%*u", size, ps->pgid);
+       sprintf(buf, "%*u", size, ps->pgid);
 }
 
 static void func_vsz(char *buf, int size, const procps_status_t *ps)
 {
        char buf5[5];
        smart_ulltoa5( ((unsigned long long)ps->vsz) << 10, buf5);
-       snprintf(buf, size+1, "%.*s", size, buf5);
+       sprintf(buf, "%.*s", size, buf5);
 }
 
+static void func_rss(char *buf, int size, const procps_status_t *ps)
+{
+       char buf5[5];
+       smart_ulltoa5( ((unsigned long long)ps->rss) << 10, buf5);
+       sprintf(buf, "%.*s", size, buf5);
+}
+
+static void func_tty(char *buf, int size, const procps_status_t *ps)
+{
+       safe_strncpy(buf, ps->tty_str, size+1);
+}
 /*
-void func_nice(char *buf, int size, const procps_status_t *ps)
+static void func_nice(char *buf, int size, const procps_status_t *ps)
 {
        ps->???
 }
 
-void func_etime(char *buf, int size, const procps_status_t *ps)
+static void func_etime(char *buf, int size, const procps_status_t *ps)
 {
        elapled time [[dd-]hh:]mm:ss
 }
 
-void func_time(char *buf, int size, const procps_status_t *ps)
+static void func_time(char *buf, int size, const procps_status_t *ps)
 {
        cumulative time [[dd-]hh:]mm:ss
 }
 
-void func_pcpu(char *buf, int size, const procps_status_t *ps)
-{
-}
-
-void func_tty(char *buf, int size, const procps_status_t *ps)
+static void func_pcpu(char *buf, int size, const procps_status_t *ps)
 {
 }
 */
 
 typedef struct {
-       char name[8];
+       uint16_t width;
+       char name[6];
        const char *header;
        void (*f)(char *buf, int size, const procps_status_t *ps);
        int ps_flags;
-       int width;
 } ps_out_t;
 
 static const ps_out_t out_spec[] = {
 // Mandated by POSIX:
-       { "user"  ,"USER"   ,func_user  ,PSSCAN_UIDGID,8                   },
-       { "comm"  ,"COMMAND",func_comm  ,PSSCAN_COMM  ,16                  },
-       { "args"  ,"COMMAND",func_args  ,PSSCAN_CMD|PSSCAN_COMM,256        },
-       { "pid"   ,"PID"    ,func_pid   ,PSSCAN_PID   ,5                   },
-       { "ppid"  ,"PPID"   ,func_ppid  ,PSSCAN_PPID  ,5                   },
-       { "pgid"  ,"PGID"   ,func_pgid  ,PSSCAN_PGID  ,5                   },
-//     { "etime" ,"ELAPSED",func_etime ,PSSCAN_      ,sizeof("ELAPSED")-1 },
-//     { "group" ,"GROUP"  ,func_group ,PSSCAN_UIDGID,sizeof("GROUP"  )-1 },
-//     { "nice"  ,"NI"     ,func_nice  ,PSSCAN_      ,sizeof("NI"     )-1 },
-//     { "pcpu"  ,"%CPU"   ,func_pcpu  ,PSSCAN_      ,sizeof("%CPU"   )-1 },
-//     { "rgroup","RGROUP" ,func_rgroup,PSSCAN_UIDGID,sizeof("RGROUP" )-1 },
-//     { "ruser" ,"RUSER"  ,func_ruser ,PSSCAN_UIDGID,sizeof("RUSER"  )-1 },
-//     { "time"  ,"TIME"   ,func_time  ,PSSCAN_      ,sizeof("TIME"   )-1 },
-//     { "tty"   ,"TT"     ,func_tty   ,PSSCAN_      ,sizeof("TT"     )-1 },
-       { "vsz"   ,"VSZ"    ,func_vsz   ,PSSCAN_VSZ   ,4                   },
-// Not mandated by POSIX:
-//     { "rss"   ,"RSS"    ,func_rss   ,PSSCAN_RSS   ,4                   },
+       { 8                  , "user"  ,"USER"   ,func_user  ,PSSCAN_UIDGID          },
+       { 16                 , "comm"  ,"COMMAND",func_comm  ,PSSCAN_COMM            },
+       { 256                , "args"  ,"COMMAND",func_args  ,PSSCAN_CMD|PSSCAN_COMM },
+       { 5                  , "pid"   ,"PID"    ,func_pid   ,PSSCAN_PID             },
+       { 5                  , "ppid"  ,"PPID"   ,func_ppid  ,PSSCAN_PPID            },
+       { 5                  , "pgid"  ,"PGID"   ,func_pgid  ,PSSCAN_PGID            },
+//     { sizeof("ELAPSED")-1, "etime" ,"ELAPSED",func_etime ,PSSCAN_                },
+//     { sizeof("GROUP"  )-1, "group" ,"GROUP"  ,func_group ,PSSCAN_UIDGID          },
+//     { sizeof("NI"     )-1, "nice"  ,"NI"     ,func_nice  ,PSSCAN_                },
+//     { sizeof("%CPU"   )-1, "pcpu"  ,"%CPU"   ,func_pcpu  ,PSSCAN_                },
+//     { sizeof("RGROUP" )-1, "rgroup","RGROUP" ,func_rgroup,PSSCAN_UIDGID          },
+//     { sizeof("RUSER"  )-1, "ruser" ,"RUSER"  ,func_ruser ,PSSCAN_UIDGID          },
+//     { sizeof("TIME"   )-1, "time"  ,"TIME"   ,func_time  ,PSSCAN_                },
+       { sizeof("TT"     )-1, "tty"   ,"TT"     ,func_tty   ,PSSCAN_TTY             },
+       { 4                  , "vsz"   ,"VSZ"    ,func_vsz   ,PSSCAN_VSZ             },
+// Not mandated by POSIX, but useful:
+       { 4                  , "rss"   ,"RSS"    ,func_rss   ,PSSCAN_RSS             },
 };
 
 #define VEC_SIZE(v) ( sizeof(v) / sizeof((v)[0]) )
@@ -152,6 +159,8 @@ static void parse_o(char* opt)
                }
                break;
        }
+       // opt points to last spec in comma separated list.
+       // This one can have =HEADER part.
        new = new_out_t();
        if (equal)
                *equal = '\0';
@@ -190,9 +199,11 @@ static void format_header(void)
 {
        int i;
        ps_out_t* op;
-       char *p = buffer;
+       char *p;
+
        if (!print_header)
                return;
+       p = buffer;
        i = 0;
        if (out_cnt) {
                while (1) {
@@ -248,7 +259,7 @@ int ps_main(int argc, char **argv)
        // -f  Generate a full listing
        // -l  Generate a long listing
        // -o col1,col2,col3=header
-       //     Select which columns to distplay
+       //     Select which columns to display
        /* We allow (and ignore) most of the above. FIXME */
        opt_complementary = "o::";
        getopt32(argc, argv, "o:aAdefl", &opt_o);
index 08357ca77d5c26dea563c7df358ec2904afbc2c5..56f2728f5b6b90c8fe2f9890159b1fa9972059a6 100644 (file)
@@ -306,7 +306,7 @@ static void __syntax(const char *file, int line)
 {
        bb_error_msg("syntax error %s:%d", file, line);
 }
-// NB: was __FILE__, but that produces full path sometimess, so...
+// NB: was __FILE__, but that produces full path sometimes, so...
 #define syntax() __syntax("hush.c", __LINE__)
 
 /* Index of subroutines: */