Magellan Linux

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

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

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 17  enum { MAX_WIDTH = 2*1024 }; Line 17  enum { MAX_WIDTH = 2*1024 };
17  #if ENABLE_DESKTOP  #if ENABLE_DESKTOP
18    
19  #include <sys/times.h> /* for times() */  #include <sys/times.h> /* for times() */
 //#include <sys/sysinfo.h> /* for sysinfo() */  
20  #ifndef AT_CLKTCK  #ifndef AT_CLKTCK
21  #define AT_CLKTCK 17  #define AT_CLKTCK 17
22  #endif  #endif
# Line 25  enum { MAX_WIDTH = 2*1024 }; Line 24  enum { MAX_WIDTH = 2*1024 };
24    
25  #if ENABLE_SELINUX  #if ENABLE_SELINUX
26  #define SELINUX_O_PREFIX "label,"  #define SELINUX_O_PREFIX "label,"
27  #define DEFAULT_O_STR    (SELINUX_O_PREFIX "pid,user" USE_FEATURE_PS_TIME(",time") ",args")  #define DEFAULT_O_STR    (SELINUX_O_PREFIX "pid,user" IF_FEATURE_PS_TIME(",time") ",args")
28  #else  #else
29  #define DEFAULT_O_STR    ("pid,user" USE_FEATURE_PS_TIME(",time") ",args")  #define DEFAULT_O_STR    ("pid,user" IF_FEATURE_PS_TIME(",time") ",args")
30  #endif  #endif
31    
32  typedef struct {  typedef struct {
33   uint16_t width;   uint16_t width;
34   char name[6];   char name6[6];
35   const char *header;   const char *header;
36   void (*f)(char *buf, int size, const procps_status_t *ps);   void (*f)(char *buf, int size, const procps_status_t *ps);
37   int ps_flags;   int ps_flags;
# Line 61  struct globals { Line 60  struct globals {
60  #define kernel_HZ          (G.kernel_HZ         )  #define kernel_HZ          (G.kernel_HZ         )
61  #define seconds_since_boot (G.seconds_since_boot)  #define seconds_since_boot (G.seconds_since_boot)
62  #define default_o          (G.default_o         )  #define default_o          (G.default_o         )
63    #define INIT_G() do { } while (0)
64    
65  #if ENABLE_FEATURE_PS_TIME  #if ENABLE_FEATURE_PS_TIME
66  /* for ELF executables, notes are pushed before environment and args */  /* for ELF executables, notes are pushed before environment and args */
# Line 143  static unsigned get_kernel_HZ(void) Line 143  static unsigned get_kernel_HZ(void)
143   kernel_HZ = get_HZ_by_waiting();   kernel_HZ = get_HZ_by_waiting();
144    
145   //if (open_read_close("/proc/uptime", buf, sizeof(buf) <= 0)   //if (open_read_close("/proc/uptime", buf, sizeof(buf) <= 0)
146   // bb_perror_msg_and_die("cannot read %s", "/proc/uptime");   // bb_perror_msg_and_die("can't read %s", "/proc/uptime");
147   //buf[sizeof(buf)-1] = '\0';   //buf[sizeof(buf)-1] = '\0';
148   ///sscanf(buf, "%llu", &seconds_since_boot);   ///sscanf(buf, "%llu", &seconds_since_boot);
149   sysinfo(&info);   sysinfo(&info);
# Line 174  static void func_user(char *buf, int siz Line 174  static void func_user(char *buf, int siz
174  #endif  #endif
175  }  }
176    
177    static 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    
182  static 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)
183  {  {
184   safe_strncpy(buf, ps->comm, size+1);   safe_strncpy(buf, ps->comm, size+1);
# Line 181  static void func_comm(char *buf, int siz Line 186  static void func_comm(char *buf, int siz
186    
187  static 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)
188  {  {
189   read_cmdline(buf, size, ps->pid, ps->comm);   read_cmdline(buf, size+1, ps->pid, ps->comm);
190  }  }
191    
192  static 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)
# Line 227  static void func_tty(char *buf, int size Line 232  static void func_tty(char *buf, int size
232   snprintf(buf, size+1, "%u,%u", ps->tty_major, ps->tty_minor);   snprintf(buf, size+1, "%u,%u", ps->tty_major, ps->tty_minor);
233  }  }
234    
235    
236    #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
237    
238    static void func_rgroup(char *buf, int size, const procps_status_t *ps)
239    {
240     safe_strncpy(buf, get_cached_groupname(ps->rgid), size+1);
241    }
242    
243    static void func_ruser(char *buf, int size, const procps_status_t *ps)
244    {
245     safe_strncpy(buf, get_cached_username(ps->ruid), size+1);
246    }
247    
248    static void func_nice(char *buf, int size, const procps_status_t *ps)
249    {
250     sprintf(buf, "%*d", size, ps->niceness);
251    }
252    
253    #endif /* FEATURE_PS_ADDITIONAL_COLUMNS */
254    
255  #if ENABLE_FEATURE_PS_TIME  #if ENABLE_FEATURE_PS_TIME
256  static 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)
257  {  {
# Line 276  static void func_pcpu(char *buf, int siz Line 301  static void func_pcpu(char *buf, int siz
301  static const ps_out_t out_spec[] = {  static const ps_out_t out_spec[] = {
302  // Mandated by POSIX:  // Mandated by POSIX:
303   { 8                  , "user"  ,"USER"   ,func_user  ,PSSCAN_UIDGID  },   { 8                  , "user"  ,"USER"   ,func_user  ,PSSCAN_UIDGID  },
304     { 8                  , "group" ,"GROUP"  ,func_group ,PSSCAN_UIDGID  },
305   { 16                 , "comm"  ,"COMMAND",func_comm  ,PSSCAN_COMM    },   { 16                 , "comm"  ,"COMMAND",func_comm  ,PSSCAN_COMM    },
306   { 256                , "args"  ,"COMMAND",func_args  ,PSSCAN_COMM    },   { MAX_WIDTH          , "args"  ,"COMMAND",func_args  ,PSSCAN_COMM    },
307   { 5                  , "pid"   ,"PID"    ,func_pid   ,PSSCAN_PID     },   { 5                  , "pid"   ,"PID"    ,func_pid   ,PSSCAN_PID     },
308   { 5                  , "ppid"  ,"PPID"   ,func_ppid  ,PSSCAN_PPID    },   { 5                  , "ppid"  ,"PPID"   ,func_ppid  ,PSSCAN_PPID    },
309   { 5                  , "pgid"  ,"PGID"   ,func_pgid  ,PSSCAN_PGID    },   { 5                  , "pgid"  ,"PGID"   ,func_pgid  ,PSSCAN_PGID    },
310  #if ENABLE_FEATURE_PS_TIME  #if ENABLE_FEATURE_PS_TIME
311   { sizeof("ELAPSED")-1, "etime" ,"ELAPSED",func_etime ,PSSCAN_START_TIME },   { sizeof("ELAPSED")-1, "etime" ,"ELAPSED",func_etime ,PSSCAN_START_TIME },
312  #endif  #endif
313  // { sizeof("GROUP"  )-1, "group" ,"GROUP"  ,func_group ,PSSCAN_UIDGID  },  #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
314  // { sizeof("NI"     )-1, "nice"  ,"NI"     ,func_nice  ,PSSCAN_        },   { 5                  , "nice"  ,"NI"     ,func_nice  ,PSSCAN_NICE    },
315  // { sizeof("%CPU"   )-1, "pcpu"  ,"%CPU"   ,func_pcpu  ,PSSCAN_        },   { 8                  , "rgroup","RGROUP" ,func_rgroup,PSSCAN_RUIDGID },
316  // { sizeof("RGROUP" )-1, "rgroup","RGROUP" ,func_rgroup,PSSCAN_UIDGID  },   { 8                  , "ruser" ,"RUSER"  ,func_ruser ,PSSCAN_RUIDGID },
317  // { sizeof("RUSER"  )-1, "ruser" ,"RUSER"  ,func_ruser ,PSSCAN_UIDGID  },  // { 5                  , "pcpu"  ,"%CPU"   ,func_pcpu  ,PSSCAN_        },
318    #endif
319  #if ENABLE_FEATURE_PS_TIME  #if ENABLE_FEATURE_PS_TIME
320   { 6                  , "time"  ,"TIME"   ,func_time  ,PSSCAN_STIME | PSSCAN_UTIME },   { 6                  , "time"  ,"TIME"   ,func_time  ,PSSCAN_STIME | PSSCAN_UTIME },
321  #endif  #endif
# Line 311  static const ps_out_t* find_out_spec(con Line 338  static const ps_out_t* find_out_spec(con
338  {  {
339   unsigned i;   unsigned i;
340   for (i = 0; i < ARRAY_SIZE(out_spec); i++) {   for (i = 0; i < ARRAY_SIZE(out_spec); i++) {
341   if (!strcmp(name, out_spec[i].name))   if (!strncmp(name, out_spec[i].name6, 6))
342   return &out_spec[i];   return &out_spec[i];
343   }   }
344   bb_error_msg_and_die("bad -o argument '%s'", name);   bb_error_msg_and_die("bad -o argument '%s'", name);
# Line 356  static void parse_o(char* opt) Line 383  static void parse_o(char* opt)
383   print_header = 1;   print_header = 1;
384  }  }
385    
386  static void post_process(void)  static void alloc_line_buffer(void)
387  {  {
388   int i;   int i;
389   int width = 0;   int width = 0;
# Line 366  static void post_process(void) Line 393  static void post_process(void)
393   print_header = 1;   print_header = 1;
394   }   }
395   width += out[i].width + 1; /* "FIELD " */   width += out[i].width + 1; /* "FIELD " */
396     if ((int)(width - terminal_width) > 0) {
397     /* The rest does not fit on the screen */
398     //out[i].width -= (width - terminal_width - 1);
399     out_cnt = i + 1;
400     break;
401     }
402   }   }
403  #if ENABLE_SELINUX  #if ENABLE_SELINUX
404   if (!is_selinux_enabled())   if (!is_selinux_enabled())
# Line 425  int ps_main(int argc UNUSED_PARAM, char Line 458  int ps_main(int argc UNUSED_PARAM, char
458  {  {
459   procps_status_t *p;   procps_status_t *p;
460   llist_t* opt_o = NULL;   llist_t* opt_o = NULL;
461   USE_SELINUX(int opt;)   int opt;
462     enum {
463     OPT_Z = (1 << 0),
464     OPT_o = (1 << 1),
465     OPT_a = (1 << 2),
466     OPT_A = (1 << 3),
467     OPT_d = (1 << 4),
468     OPT_e = (1 << 5),
469     OPT_f = (1 << 6),
470     OPT_l = (1 << 7),
471     OPT_T = (1 << 8) * ENABLE_FEATURE_SHOW_THREADS,
472     };
473    
474     INIT_G();
475    
476   // POSIX:   // POSIX:
477   // -a  Write information for all processes associated with terminals   // -a  Write information for all processes associated with terminals
478   //     Implementations may omit session leaders from this list   //     Implementations may omit session leaders from this list
479   // -A  Write information for all processes   // -A  Write information for all processes
480   // -d  Write information for all processes, except session leaders   // -d  Write information for all processes, except session leaders
481   // -e  Write information for all processes (equivalent to -A.)   // -e  Write information for all processes (equivalent to -A)
482   // -f  Generate a full listing   // -f  Generate a full listing
483   // -l  Generate a long listing   // -l  Generate a long listing
484   // -o col1,col2,col3=header   // -o col1,col2,col3=header
485   //     Select which columns to display   //     Select which columns to display
486   /* We allow (and ignore) most of the above. FIXME */   /* We allow (and ignore) most of the above. FIXME.
487     * -T is picked for threads (POSIX hasn't it standardized).
488     * procps v3.2.7 supports -T and shows tids as SPID column,
489     * it also supports -L where it shows tids as LWP column.
490     */
491   opt_complementary = "o::";   opt_complementary = "o::";
492   USE_SELINUX(opt =) getopt32(argv, "Zo:aAdefl", &opt_o);   opt = getopt32(argv, "Zo:aAdefl"IF_FEATURE_SHOW_THREADS("T"), &opt_o);
493   if (opt_o) {   if (opt_o) {
494   do {   do {
495   parse_o(llist_pop(&opt_o));   parse_o(llist_pop(&opt_o));
# Line 447  int ps_main(int argc UNUSED_PARAM, char Line 497  int ps_main(int argc UNUSED_PARAM, char
497   } else {   } else {
498   /* Below: parse_o() needs char*, NOT const char*... */   /* Below: parse_o() needs char*, NOT const char*... */
499  #if ENABLE_SELINUX  #if ENABLE_SELINUX
500   if (!(opt & 1) || !is_selinux_enabled()) {   if (!(opt & OPT_Z) || !is_selinux_enabled()) {
501   /* no -Z or no SELinux: do not show LABEL */   /* no -Z or no SELinux: do not show LABEL */
502   strcpy(default_o, DEFAULT_O_STR + sizeof(SELINUX_O_PREFIX)-1);   strcpy(default_o, DEFAULT_O_STR + sizeof(SELINUX_O_PREFIX)-1);
503   } else   } else
# Line 457  int ps_main(int argc UNUSED_PARAM, char Line 507  int ps_main(int argc UNUSED_PARAM, char
507   }   }
508   parse_o(default_o);   parse_o(default_o);
509   }   }
510   post_process();  #if ENABLE_FEATURE_SHOW_THREADS
511     if (opt & OPT_T)
512     need_flags |= PSSCAN_TASKS;
513    #endif
514    
515   /* Was INT_MAX, but some libc's go belly up with printf("%.*s")   /* Was INT_MAX, but some libc's go belly up with printf("%.*s")
516   * and such large widths */   * and such large widths */
# Line 467  int ps_main(int argc UNUSED_PARAM, char Line 520  int ps_main(int argc UNUSED_PARAM, char
520   if (--terminal_width > MAX_WIDTH)   if (--terminal_width > MAX_WIDTH)
521   terminal_width = MAX_WIDTH;   terminal_width = MAX_WIDTH;
522   }   }
523     alloc_line_buffer();
524   format_header();   format_header();
525    
526   p = NULL;   p = NULL;
527   while ((p = procps_scan(p, need_flags))) {   while ((p = procps_scan(p, need_flags)) != NULL) {
528   format_process(p);   format_process(p);
529   }   }
530    
# Line 484  int ps_main(int argc UNUSED_PARAM, char Line 538  int ps_main(int argc UNUSED_PARAM, char
538  int ps_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;  int ps_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
539  int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)  int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
540  {  {
541   procps_status_t *p = NULL;   procps_status_t *p;
542   int len;   int len;
543   SKIP_SELINUX(const) int use_selinux = 0;   int psscan_flags = PSSCAN_PID | PSSCAN_UIDGID
544   USE_SELINUX(int i;)   | PSSCAN_STATE | PSSCAN_VSZ | PSSCAN_COMM;
545  #if !ENABLE_FEATURE_PS_WIDE  #if !ENABLE_FEATURE_PS_WIDE
546   enum { terminal_width = 79 };   enum { terminal_width = 79 };
547  #else  #else
548   unsigned terminal_width;   unsigned terminal_width;
  int w_count = 0;  
549  #endif  #endif
550    
551  #if ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX  #if ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX
552  #if ENABLE_FEATURE_PS_WIDE   int opts;
553    # if ENABLE_FEATURE_PS_WIDE
554     int w_count = 0;
555   opt_complementary = "-:ww";   opt_complementary = "-:ww";
556   USE_SELINUX(i =) getopt32(argv, USE_SELINUX("Z") "w", &w_count);   opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")"w", &w_count);
557   /* if w is given once, GNU ps sets the width to 132,   /* if w is given once, GNU ps sets the width to 132,
558   * if w is given more than once, it is "unlimited"   * if w is given more than once, it is "unlimited"
559   */   */
560   if (w_count) {   if (w_count) {
561   terminal_width = (w_count==1) ? 132 : MAX_WIDTH;   terminal_width = (w_count == 1) ? 132 : MAX_WIDTH;
562   } else {   } else {
563   get_terminal_width_height(0, &terminal_width, NULL);   get_terminal_width_height(0, &terminal_width, NULL);
564   /* Go one less... */   /* Go one less... */
565   if (--terminal_width > MAX_WIDTH)   if (--terminal_width > MAX_WIDTH)
566   terminal_width = MAX_WIDTH;   terminal_width = MAX_WIDTH;
567   }   }
568  #else /* only ENABLE_SELINUX */  # else /* only ENABLE_SELINUX */
569   i = getopt32(argv, "Z");   opts = getopt32(argv, "Z"IF_FEATURE_SHOW_THREADS("T"));
570  #endif  # endif
571  #if ENABLE_SELINUX  # if ENABLE_SELINUX
572   if ((i & 1) && is_selinux_enabled())   if ((opts & 1) && is_selinux_enabled())
573   use_selinux = PSSCAN_CONTEXT;   psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT
574  #endif   | PSSCAN_STATE | PSSCAN_COMM;
575    # endif
576    # if ENABLE_FEATURE_SHOW_THREADS
577     if (opts & (1 << ENABLE_SELINUX))
578     psscan_flags |= PSSCAN_TASKS;
579    # endif
580  #endif /* ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX */  #endif /* ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX */
581    
582   if (use_selinux)   if (psscan_flags & PSSCAN_CONTEXT)
583   puts("  PID CONTEXT                          STAT COMMAND");   puts("  PID CONTEXT                          STAT COMMAND");
584   else   else
585   puts("  PID USER       VSZ STAT COMMAND");   puts("  PID USER       VSZ STAT COMMAND");
586    
587   while ((p = procps_scan(p, 0   p = NULL;
588   | PSSCAN_PID   while ((p = procps_scan(p, psscan_flags)) != NULL) {
  | PSSCAN_UIDGID  
  | PSSCAN_STATE  
  | PSSCAN_VSZ  
  | PSSCAN_COMM  
  | use_selinux  
  ))) {  
589  #if ENABLE_SELINUX  #if ENABLE_SELINUX
590   if (use_selinux) {   if (psscan_flags & PSSCAN_CONTEXT) {
591   len = printf("%5u %-32.32s %s  ",   len = printf("%5u %-32.32s %s  ",
592   p->pid,   p->pid,
593   p->context ? p->context : "unknown",   p->context ? p->context : "unknown",

Legend:
Removed from v.983  
changed lines
  Added in v.984