Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/procps/ps.c
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/procps/ps.c
r2725 r3232 10 10 */ 11 11 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 12 64 #include "libbb.h" 65 #ifdef __linux__ 66 # include <sys/sysinfo.h> 67 #endif 13 68 14 69 /* Absolute maximum on output line length */ 15 70 enum { MAX_WIDTH = 2*1024 }; 16 71 72 #if ENABLE_FEATURE_PS_TIME || ENABLE_FEATURE_PS_LONG 73 static 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 17 97 #if ENABLE_DESKTOP 18 98 19 99 #include <sys/times.h> /* for times() */ 20 100 #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 */ 32 124 typedef struct { 33 125 uint16_t width; … … 49 141 unsigned long long seconds_since_boot; 50 142 #endif 51 char default_o[sizeof(DEFAULT_O_STR)];52 143 } FIX_ALIASING; 53 144 #define G (*(struct globals*)&bb_common_bufsiz1) … … 60 151 #define kernel_HZ (G.kernel_HZ ) 61 152 #define seconds_since_boot (G.seconds_since_boot) 62 #define default_o (G.default_o )63 153 #define INIT_G() do { } while (0) 64 154 … … 69 159 ptrdiff_t *ep = (ptrdiff_t *) environ; 70 160 71 while (*ep++); 161 while (*ep++) 162 continue; 72 163 while (*ep) { 73 164 if (ep[0] == findme) { … … 132 223 static unsigned get_kernel_HZ(void) 133 224 { 134 //char buf[64];135 struct sysinfo info;136 225 137 226 if (kernel_HZ) … … 143 232 kernel_HZ = get_HZ_by_waiting(); 144 233 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(); 151 235 152 236 return kernel_HZ; … … 185 269 } 186 270 271 static void func_state(char *buf, int size, const procps_status_t *ps) 272 { 273 safe_strncpy(buf, ps->state, size+1); 274 } 275 187 276 static void func_args(char *buf, int size, const procps_status_t *ps) 188 277 { … … 301 390 302 391 static const ps_out_t out_spec[] = { 303 / / Mandated by POSIX:392 /* Mandated by http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html: */ 304 393 { 8 , "user" ,"USER" ,func_user ,PSSCAN_UIDGID }, 305 394 { 8 , "group" ,"GROUP" ,func_group ,PSSCAN_UIDGID }, … … 323 412 { 6 , "tty" ,"TT" ,func_tty ,PSSCAN_TTY }, 324 413 { 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 }, 326 416 { 4 , "rss" ,"RSS" ,func_rss ,PSSCAN_RSS }, 327 417 #if ENABLE_SELINUX … … 460 550 } 461 551 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 462 559 int ps_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 463 560 int ps_main(int argc UNUSED_PARAM, char **argv) … … 465 562 procps_status_t *p; 466 563 llist_t* opt_o = NULL; 564 char default_o[sizeof(DEFAULT_O_STR)]; 467 565 int opt; 468 566 enum { … … 502 600 } while (opt_o); 503 601 } 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 */ 505 603 #if ENABLE_SELINUX 506 604 if (!(opt & OPT_Z) || !is_selinux_enabled()) { … … 552 650 OPT_Z = (1 << 0) * ENABLE_SELINUX, 553 651 OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS, 652 OPT_l = (1 << ENABLE_SELINUX) * (1 << ENABLE_FEATURE_SHOW_THREADS) * ENABLE_FEATURE_PS_LONG, 554 653 }; 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 555 660 int opts = 0; 556 /* If we support any options, parse argv */557 #if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE558 661 # if ENABLE_FEATURE_PS_WIDE 559 662 /* -w is a bit complicated */ 560 663 int w_count = 0; 561 664 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); 563 667 /* if w is given once, GNU ps sets the width to 132, 564 668 * if w is given more than once, it is "unlimited" … … 575 679 /* -w is not supported, only -Z and/or -T */ 576 680 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")); 578 682 # endif 579 #endif 580 581 #if ENABLE_SELINUX 683 684 # if ENABLE_SELINUX 582 685 if ((opts & OPT_Z) && is_selinux_enabled()) { 583 686 psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT … … 585 688 puts(" PID CONTEXT STAT COMMAND"); 586 689 } 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 { 589 720 puts(" PID USER VSZ STAT COMMAND"); 590 721 } … … 592 723 psscan_flags |= PSSCAN_TASKS; 593 724 } 725 #endif 594 726 595 727 p = NULL; … … 605 737 #endif 606 738 { 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 612 780 { 613 char buf6[6]; 614 smart_ulltoa5(p->vsz, buf6, " mgtpezy"); 615 buf6[5] = '\0'; 781 const char *user = get_cached_username(p->uid); 616 782 len = printf("%5u %-8.8s %s %s ", 617 783 p->pid, user, buf6, p->state);
Note:
See TracChangeset
for help on using the changeset viewer.