Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/procps/ps.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 532 by niro, Sat Sep 1 22:45:15 2007 UTC revision 816 by niro, Fri Apr 24 18:33:46 2009 UTC
# Line 3  Line 3 
3   * Mini ps implementation(s) for busybox   * Mini ps implementation(s) for busybox
4   *   *
5   * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>   * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6     * Fix for SELinux Support:(c)2007 Hiroshi Shinji <shiroshi@my.email.ne.jp>
7     *                         (c)2007 Yuichi Nakamura <ynakam@hitachisoft.jp>
8   *   *
9   * Licensed under the GPL version 2, see the file LICENSE in this tarball.   * Licensed under the GPL version 2, see the file LICENSE in this tarball.
10   */   */
11    
12  #include "busybox.h"  #include "libbb.h"
13    
14    /* Absolute maximum on output line length */
15    enum { MAX_WIDTH = 2*1024 };
16    
17  #if ENABLE_DESKTOP  #if ENABLE_DESKTOP
18    
19    #include <sys/times.h> /* for times() */
20    //#include <sys/sysinfo.h> /* for sysinfo() */
21    #ifndef AT_CLKTCK
22    #define AT_CLKTCK 17
23    #endif
24    
25    
26    #if ENABLE_SELINUX
27    #define SELINUX_O_PREFIX "label,"
28    #define DEFAULT_O_STR    (SELINUX_O_PREFIX "pid,user" USE_FEATURE_PS_TIME(",time") ",args")
29    #else
30    #define DEFAULT_O_STR    ("pid,user" USE_FEATURE_PS_TIME(",time") ",args")
31    #endif
32    
33    typedef struct {
34     uint16_t width;
35     char name[6];
36     const char *header;
37     void (*f)(char *buf, int size, const procps_status_t *ps);
38     int ps_flags;
39    } ps_out_t;
40    
41    struct globals {
42     ps_out_t* out;
43     int out_cnt;
44     int print_header;
45     int need_flags;
46     char *buffer;
47     unsigned terminal_width;
48    #if ENABLE_FEATURE_PS_TIME
49     unsigned kernel_HZ;
50     unsigned long long seconds_since_boot;
51    #endif
52     char default_o[sizeof(DEFAULT_O_STR)];
53    };
54    #define G (*(struct globals*)&bb_common_bufsiz1)
55    #define out                (G.out               )
56    #define out_cnt            (G.out_cnt           )
57    #define print_header       (G.print_header      )
58    #define need_flags         (G.need_flags        )
59    #define buffer             (G.buffer            )
60    #define terminal_width     (G.terminal_width    )
61    #define kernel_HZ          (G.kernel_HZ         )
62    #define seconds_since_boot (G.seconds_since_boot)
63    #define default_o          (G.default_o         )
64    
65    #if ENABLE_FEATURE_PS_TIME
66    /* for ELF executables, notes are pushed before environment and args */
67    static 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
82    static 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
125    static inline unsigned get_HZ_by_waiting(void)
126    {
127     /* Better method? */
128     return 100;
129    }
130    #endif
131    
132    static 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("cannot 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') */  /* Print value to buf, max size+1 chars (including trailing '\0') */
157    
158  void func_user(char *buf, int size, const procps_status_t *ps)  static 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);   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    
177  void func_comm(char *buf, int size, const procps_status_t *ps)  static void func_comm(char *buf, int size, const procps_status_t *ps)
178  {  {
179   safe_strncpy(buf, ps->comm, size+1);   safe_strncpy(buf, ps->comm, size+1);
180  }  }
181    
182  void func_args(char *buf, int size, const procps_status_t *ps)  static void func_args(char *buf, int size, const procps_status_t *ps)
183  {  {
184   buf[0] = '\0';   read_cmdline(buf, size, ps->pid, ps->comm);
  if (ps->cmd)  
  safe_strncpy(buf, ps->cmd, size+1);  
  else if (size >= 2)  
  snprintf(buf, size+1, "[%.*s]", size-2, ps->comm);  
185  }  }
186    
187  void func_pid(char *buf, int size, const procps_status_t *ps)  static void func_pid(char *buf, int size, const procps_status_t *ps)
188  {  {
189   snprintf(buf, size+1, "%*u", size, ps->pid);   sprintf(buf, "%*u", size, ps->pid);
190  }  }
191    
192  void func_ppid(char *buf, int size, const procps_status_t *ps)  static void func_ppid(char *buf, int size, const procps_status_t *ps)
193  {  {
194   snprintf(buf, size+1, "%*u", size, ps->ppid);   sprintf(buf, "%*u", size, ps->ppid);
195  }  }
196    
197  void func_pgid(char *buf, int size, const procps_status_t *ps)  static void func_pgid(char *buf, int size, const procps_status_t *ps)
198  {  {
199   snprintf(buf, size+1, "%*u", size, ps->pgid);   sprintf(buf, "%*u", size, ps->pgid);
200  }  }
201    
202  void func_rss(char *buf, int size, const procps_status_t *ps)  static void put_lu(char *buf, int size, unsigned long u)
203  {  {
204   char buf5[5];   char buf4[5];
205   smart_ulltoa5( ((unsigned long long)ps->rss) << 10, buf5);  
206   snprintf(buf, size+1, "%.*s", size, buf5);   /* see http://en.wikipedia.org/wiki/Tera */
207     smart_ulltoa4(u, buf4, " mgtpezy");
208     buf4[4] = '\0';
209     sprintf(buf, "%.*s", size, buf4);
210  }  }
211    
212  /*  static void func_vsz(char *buf, int size, const procps_status_t *ps)
 void func_nice(char *buf, int size, const procps_status_t *ps)  
213  {  {
214   ps->???   put_lu(buf, size, ps->vsz);
215    }
216    
217    static void func_rss(char *buf, int size, const procps_status_t *ps)
218    {
219     put_lu(buf, size, ps->rss);
220  }  }
221    
222  void func_etime(char *buf, int size, const procps_status_t *ps)  static void func_tty(char *buf, int size, const procps_status_t *ps)
223  {  {
224   elapled time [[dd-]hh:]mm:ss   buf[0] = '?';
225     buf[1] = '\0';
226     if (ps->tty_major) /* tty field of "0" means "no tty" */
227     snprintf(buf, size+1, "%u,%u", ps->tty_major, ps->tty_minor);
228  }  }
229    
230  void func_time(char *buf, int size, const procps_status_t *ps)  #if ENABLE_FEATURE_PS_TIME
231    static void func_etime(char *buf, int size, const procps_status_t *ps)
232  {  {
233   cumulative time [[dd-]hh:]mm:ss   /* elapsed time [[dd-]hh:]mm:ss; here only mm:ss */
234     unsigned long mm;
235     unsigned ss;
236    
237     mm = ps->start_time / get_kernel_HZ();
238     /* must be after get_kernel_HZ()! */
239     mm = seconds_since_boot - mm;
240     ss = mm % 60;
241     mm /= 60;
242     snprintf(buf, size+1, "%3lu:%02u", mm, ss);
243  }  }
244    
245  void func_pcpu(char *buf, int size, const procps_status_t *ps)  static void func_time(char *buf, int size, const procps_status_t *ps)
246  {  {
247     /* cumulative time [[dd-]hh:]mm:ss; here only mm:ss */
248     unsigned long mm;
249     unsigned ss;
250    
251     mm = (ps->utime + ps->stime) / get_kernel_HZ();
252     ss = mm % 60;
253     mm /= 60;
254     snprintf(buf, size+1, "%3lu:%02u", mm, ss);
255  }  }
256    #endif
257    
258  void func_tty(char *buf, int size, const procps_status_t *ps)  #if ENABLE_SELINUX
259    static void func_label(char *buf, int size, const procps_status_t *ps)
260  {  {
261     safe_strncpy(buf, ps->context ? ps->context : "unknown", size+1);
262  }  }
263  */  #endif
264    
265  typedef struct {  /*
266   char name[8];  static void func_nice(char *buf, int size, const procps_status_t *ps)
267   const char *header;  {
268   void (*f)(char *buf, int size, const procps_status_t *ps);   ps->???
269   int ps_flags;  }
270   int width;  
271  } ps_out_t;  static void func_pcpu(char *buf, int size, const procps_status_t *ps)
272    {
273    }
274    */
275    
276  static const ps_out_t out_spec[] = {  static const ps_out_t out_spec[] = {
277  // Mandated by POSIX:  // Mandated by POSIX:
278   { "user"  ,"USER"   ,func_user  ,PSSCAN_UIDGID,8                   },   { 8                  , "user"  ,"USER"   ,func_user  ,PSSCAN_UIDGID  },
279   { "comm"  ,"COMMAND",func_comm  ,PSSCAN_COMM  ,16                  },   { 16                 , "comm"  ,"COMMAND",func_comm  ,PSSCAN_COMM    },
280   { "args"  ,"COMMAND",func_args  ,PSSCAN_CMD|PSSCAN_COMM,256        },   { 256                , "args"  ,"COMMAND",func_args  ,PSSCAN_COMM    },
281   { "pid"   ,"PID"    ,func_pid   ,PSSCAN_PID   ,5                   },   { 5                  , "pid"   ,"PID"    ,func_pid   ,PSSCAN_PID     },
282   { "ppid"  ,"PPID"   ,func_ppid  ,PSSCAN_PPID  ,5                   },   { 5                  , "ppid"  ,"PPID"   ,func_ppid  ,PSSCAN_PPID    },
283   { "pgid"  ,"PGID"   ,func_pgid  ,PSSCAN_PGID  ,5                   },   { 5                  , "pgid"  ,"PGID"   ,func_pgid  ,PSSCAN_PGID    },
284  // { "etime" ,"ELAPSED",func_etime ,PSSCAN_      ,sizeof("ELAPSED")-1 },  #if ENABLE_FEATURE_PS_TIME
285  // { "group" ,"GROUP"  ,func_group ,PSSCAN_UIDGID,sizeof("GROUP"  )-1 },   { sizeof("ELAPSED")-1, "etime" ,"ELAPSED",func_etime ,PSSCAN_START_TIME },
286  // { "nice"  ,"NI"     ,func_nice  ,PSSCAN_      ,sizeof("NI"     )-1 },  #endif
287  // { "pcpu"  ,"%CPU"   ,func_pcpu  ,PSSCAN_      ,sizeof("%CPU"   )-1 },  // { sizeof("GROUP"  )-1, "group" ,"GROUP"  ,func_group ,PSSCAN_UIDGID  },
288  // { "rgroup","RGROUP" ,func_rgroup,PSSCAN_UIDGID,sizeof("RGROUP" )-1 },  // { sizeof("NI"     )-1, "nice"  ,"NI"     ,func_nice  ,PSSCAN_        },
289  // { "ruser" ,"RUSER"  ,func_ruser ,PSSCAN_UIDGID,sizeof("RUSER"  )-1 },  // { sizeof("%CPU"   )-1, "pcpu"  ,"%CPU"   ,func_pcpu  ,PSSCAN_        },
290  // { "time"  ,"TIME"   ,func_time  ,PSSCAN_      ,sizeof("TIME"   )-1 },  // { sizeof("RGROUP" )-1, "rgroup","RGROUP" ,func_rgroup,PSSCAN_UIDGID  },
291  // { "tty"   ,"TT"     ,func_tty   ,PSSCAN_      ,sizeof("TT"     )-1 },  // { sizeof("RUSER"  )-1, "ruser" ,"RUSER"  ,func_ruser ,PSSCAN_UIDGID  },
292  // { "vsz"   ,"VSZ"    ,func_vsz   ,PSSCAN_VSZ   ,4                   },  #if ENABLE_FEATURE_PS_TIME
293  // Not mandated by POSIX:   { 6                  , "time"  ,"TIME"   ,func_time  ,PSSCAN_STIME | PSSCAN_UTIME },
294   { "rss"   ,"RSS"    ,func_rss   ,PSSCAN_RSS   ,4                   },  #endif
295     { 6                  , "tty"   ,"TT"     ,func_tty   ,PSSCAN_TTY     },
296     { 4                  , "vsz"   ,"VSZ"    ,func_vsz   ,PSSCAN_VSZ     },
297    // Not mandated by POSIX, but useful:
298     { 4                  , "rss"   ,"RSS"    ,func_rss   ,PSSCAN_RSS     },
299    #if ENABLE_SELINUX
300     { 35                 , "label" ,"LABEL"  ,func_label ,PSSCAN_CONTEXT },
301    #endif
302  };  };
303    
 #define VEC_SIZE(v) ( sizeof(v) / sizeof((v)[0]) )  
   
 static ps_out_t* out;  
 static int out_cnt;  
 static int print_header;  
 static int ps_flags;  
 static char *buffer;  
 static unsigned terminal_width;  
   
   
304  static ps_out_t* new_out_t(void)  static ps_out_t* new_out_t(void)
305  {  {
306   int i = out_cnt++;   out = xrealloc_vector(out, 2, out_cnt);
307   out = xrealloc(out, out_cnt * sizeof(*out));   return &out[out_cnt++];
  return &out[i];  
308  }  }
309    
310  static const ps_out_t* find_out_spec(const char *name)  static const ps_out_t* find_out_spec(const char *name)
311  {  {
312   int i;   unsigned i;
313   for (i = 0; i < VEC_SIZE(out_spec); i++) {   for (i = 0; i < ARRAY_SIZE(out_spec); i++) {
314   if (!strcmp(name, out_spec[i].name))   if (!strcmp(name, out_spec[i].name))
315   return &out_spec[i];   return &out_spec[i];
316   }   }
# Line 152  static void parse_o(char* opt) Line 334  static void parse_o(char* opt)
334   }   }
335   break;   break;
336   }   }
337     // opt points to last spec in comma separated list.
338     // This one can have =HEADER part.
339   new = new_out_t();   new = new_out_t();
340   if (equal)   if (equal)
341   *equal = '\0';   *equal = '\0';
# Line 177  static void post_process(void) Line 361  static void post_process(void)
361   int i;   int i;
362   int width = 0;   int width = 0;
363   for (i = 0; i < out_cnt; i++) {   for (i = 0; i < out_cnt; i++) {
364   ps_flags |= out[i].ps_flags;   need_flags |= out[i].ps_flags;
365   if (out[i].header[0]) {   if (out[i].header[0]) {
366   print_header = 1;   print_header = 1;
367   }   }
368   width += out[i].width + 1; /* "FIELD " */   width += out[i].width + 1; /* "FIELD " */
369   }   }
370    #if ENABLE_SELINUX
371     if (!is_selinux_enabled())
372     need_flags &= ~PSSCAN_CONTEXT;
373    #endif
374   buffer = xmalloc(width + 1); /* for trailing \0 */   buffer = xmalloc(width + 1); /* for trailing \0 */
375  }  }
376    
# Line 190  static void format_header(void) Line 378  static void format_header(void)
378  {  {
379   int i;   int i;
380   ps_out_t* op;   ps_out_t* op;
381   char *p = buffer;   char *p;
382    
383   if (!print_header)   if (!print_header)
384   return;   return;
385     p = buffer;
386   i = 0;   i = 0;
387   if (out_cnt) {   if (out_cnt) {
388   while (1) {   while (1) {
# Line 230  static void format_process(const procps_ Line 420  static void format_process(const procps_
420   printf("%.*s\n", terminal_width, buffer);   printf("%.*s\n", terminal_width, buffer);
421  }  }
422    
423  /* Cannot be const: parse_o() will choke */  int ps_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
424  static char default_o[] = "pid,user" /* TODO: ,vsz,stat */ ",args";  int ps_main(int argc UNUSED_PARAM, char **argv)
   
 int ps_main(int argc, char **argv)  
425  {  {
426   procps_status_t *p;   procps_status_t *p;
427   llist_t* opt_o = NULL;   llist_t* opt_o = NULL;
428     USE_SELINUX(int opt;)
429    
430   // POSIX:   // POSIX:
431   // -a  Write information for all processes associated with terminals   // -a  Write information for all processes associated with terminals
# Line 247  int ps_main(int argc, char **argv) Line 436  int ps_main(int argc, char **argv)
436   // -f  Generate a full listing   // -f  Generate a full listing
437   // -l  Generate a long listing   // -l  Generate a long listing
438   // -o col1,col2,col3=header   // -o col1,col2,col3=header
439   //     Select which columns to distplay   //     Select which columns to display
440   /* We allow (and ignore) most of the above. FIXME */   /* We allow (and ignore) most of the above. FIXME */
441   opt_complementary = "o::";   opt_complementary = "o::";
442   getopt32(argc, argv, "o:aAdefl", &opt_o);   USE_SELINUX(opt =) getopt32(argv, "Zo:aAdefl", &opt_o);
443   if (opt_o) {   if (opt_o) {
  opt_o = rev_llist(opt_o);  
444   do {   do {
445   parse_o(opt_o->data);   parse_o(llist_pop(&opt_o));
  opt_o = opt_o->link;  
446   } while (opt_o);   } while (opt_o);
447   } else   } else {
448     /* Below: parse_o() needs char*, NOT const char*... */
449    #if ENABLE_SELINUX
450     if (!(opt & 1) || !is_selinux_enabled()) {
451     /* no -Z or no SELinux: do not show LABEL */
452     strcpy(default_o, DEFAULT_O_STR + sizeof(SELINUX_O_PREFIX)-1);
453     } else
454    #endif
455     {
456     strcpy(default_o, DEFAULT_O_STR);
457     }
458   parse_o(default_o);   parse_o(default_o);
459     }
460   post_process();   post_process();
461    
462   terminal_width = INT_MAX;   /* Was INT_MAX, but some libc's go belly up with printf("%.*s")
463     * and such large widths */
464     terminal_width = MAX_WIDTH;
465   if (isatty(1)) {   if (isatty(1)) {
466   get_terminal_width_height(1, &terminal_width, NULL);   get_terminal_width_height(0, &terminal_width, NULL);
467   terminal_width--;   if (--terminal_width > MAX_WIDTH)
468     terminal_width = MAX_WIDTH;
469   }   }
470   format_header();   format_header();
471    
472   p = NULL;   p = NULL;
473   while ((p = procps_scan(p, ps_flags))) {   while ((p = procps_scan(p, need_flags))) {
474   format_process(p);   format_process(p);
475   }   }
476    
# Line 280  int ps_main(int argc, char **argv) Line 481  int ps_main(int argc, char **argv)
481  #else /* !ENABLE_DESKTOP */  #else /* !ENABLE_DESKTOP */
482    
483    
484  int ps_main(int argc, char **argv)  int ps_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
485    int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
486  {  {
487   procps_status_t *p = NULL;   procps_status_t *p = NULL;
488   int i, len;   int len;
489   SKIP_SELINUX(const) int use_selinux = 0;   SKIP_SELINUX(const) int use_selinux = 0;
490   USE_SELINUX(security_context_t sid = NULL;)   USE_SELINUX(int i;)
491  #if !ENABLE_FEATURE_PS_WIDE  #if !ENABLE_FEATURE_PS_WIDE
492   enum { terminal_width = 79 };   enum { terminal_width = 79 };
493  #else  #else
494   int terminal_width;   unsigned terminal_width;
495   int w_count = 0;   int w_count = 0;
496  #endif  #endif
497    
498  #if ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX  #if ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX
499  #if ENABLE_FEATURE_PS_WIDE  #if ENABLE_FEATURE_PS_WIDE
500   opt_complementary = "-:ww";   opt_complementary = "-:ww";
501   USE_SELINUX(i =) getopt32(argc, argv, USE_SELINUX("c") "w", &w_count);   USE_SELINUX(i =) getopt32(argv, USE_SELINUX("Z") "w", &w_count);
502   /* if w is given once, GNU ps sets the width to 132,   /* if w is given once, GNU ps sets the width to 132,
503   * if w is given more than once, it is "unlimited"   * if w is given more than once, it is "unlimited"
504   */   */
505   if (w_count) {   if (w_count) {
506   terminal_width = (w_count==1) ? 132 : INT_MAX;   terminal_width = (w_count==1) ? 132 : MAX_WIDTH;
507   } else {   } else {
508   get_terminal_width_height(1, &terminal_width, NULL);   get_terminal_width_height(0, &terminal_width, NULL);
509   /* Go one less... */   /* Go one less... */
510   terminal_width--;   if (--terminal_width > MAX_WIDTH)
511     terminal_width = MAX_WIDTH;
512   }   }
513  #else /* only ENABLE_SELINUX */  #else /* only ENABLE_SELINUX */
514   i = getopt32(argc, argv, "c");   i = getopt32(argv, "Z");
515  #endif  #endif
516  #if ENABLE_SELINUX  #if ENABLE_SELINUX
517   if ((i & 1) && is_selinux_enabled())   if ((i & 1) && is_selinux_enabled())
518   use_selinux = 1;   use_selinux = PSSCAN_CONTEXT;
519  #endif  #endif
520  #endif /* ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX */  #endif /* ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX */
521    
522   if (use_selinux)   if (use_selinux)
523   puts("  PID Context                          Stat Command");   puts("  PID CONTEXT                          STAT COMMAND");
524   else   else
525   puts("  PID  Uid     VmSize Stat Command");   puts("  PID USER       VSZ STAT COMMAND");
526    
527   while ((p = procps_scan(p, 0   while ((p = procps_scan(p, 0
528   | PSSCAN_PID   | PSSCAN_PID
529   | PSSCAN_UIDGID   | PSSCAN_UIDGID
530   | PSSCAN_STATE   | PSSCAN_STATE
531   | PSSCAN_RSS   | PSSCAN_VSZ
532   | PSSCAN_CMD   | PSSCAN_COMM
533     | use_selinux
534   ))) {   ))) {
  char *namecmd = p->cmd;  
535  #if ENABLE_SELINUX  #if ENABLE_SELINUX
536   if (use_selinux) {   if (use_selinux) {
537   char sbuf[128];   len = printf("%5u %-32.32s %s  ",
538   len = sizeof(sbuf);   p->pid,
539     p->context ? p->context : "unknown",
540   if (is_selinux_enabled()) {   p->state);
  if (getpidcon(p->pid, &sid) < 0)  
  sid = NULL;  
  }  
   
  if (sid) {  
  /* I assume sid initialized with NULL */  
  len = strlen(sid) + 1;  
  safe_strncpy(sbuf, sid, len);  
  freecon(sid);  
  sid = NULL;  
  } else {  
  safe_strncpy(sbuf, "unknown", 7);  
  }  
  len = printf("%5u %-32s %s ", p->pid, sbuf, p->state);  
541   } else   } else
542  #endif  #endif
543   {   {
544   const char *user = get_cached_username(p->uid);   const char *user = get_cached_username(p->uid);
545   if (p->rss == 0)   //if (p->vsz == 0)
546   len = printf("%5u %-8s        %s ",   // len = printf("%5u %-8.8s        %s ",
547   p->pid, user, p->state);   // p->pid, user, p->state);
548   else   //else
549   len = printf("%5u %-8s %6ld %s ",   {
550   p->pid, user, p->rss, p->state);   char buf6[6];
551     smart_ulltoa5(p->vsz, buf6, " mgtpezy");
552     buf6[5] = '\0';
553     len = printf("%5u %-8.8s %s %s  ",
554     p->pid, user, buf6, p->state);
555     }
556   }   }
557    
558   i = terminal_width-len;   {
559     int sz = terminal_width - len;
560   if (namecmd && namecmd[0]) {   char buf[sz + 1];
561   if (i < 0)   read_cmdline(buf, sz, p->pid, p->comm);
562   i = 0;   puts(buf);
  if (strlen(namecmd) > (size_t)i)  
  namecmd[i] = 0;  
  puts(namecmd);  
  } else {  
  namecmd = p->comm;  
  if (i < 2)  
  i = 2;  
  if (strlen(namecmd) > ((size_t)i-2))  
  namecmd[i-2] = 0;  
  printf("[%s]\n", namecmd);  
563   }   }
564   }   }
565   if (ENABLE_FEATURE_CLEAN_UP)   if (ENABLE_FEATURE_CLEAN_UP)

Legend:
Removed from v.532  
changed lines
  Added in v.816