Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/procps


Ignore:
Timestamp:
Jan 1, 2014, 12:47:38 AM (10 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.21.1
Location:
branches/3.2/mindi-busybox/procps
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • branches/3.2/mindi-busybox/procps/Config.src

    r2725 r3232  
    1111    bool "free"
    1212    default y
    13     depends on PLATFORM_LINUX #sysinfo()
     13    select PLATFORM_LINUX #sysinfo()
    1414    help
    1515      free displays the total amount of free and used physical and swap
     
    4646    default y
    4747    depends on KILL
    48 
    49 config NMETER
    50     bool "nmeter"
    51     default y
    52     help
    53       Prints selected system stats continuously, one line per update.
    5448
    5549config PGREP
     
    9791    bool "Enable wide output option (-w)"
    9892    default y
    99     depends on PS
     93    depends on PS && !DESKTOP
    10094    help
    10195      Support argument 'w' for wide output.
     
    10397      than once, the length is unlimited.
    10498
     99config FEATURE_PS_LONG
     100    bool "Enable long output option (-l)"
     101    default y
     102    depends on PS && !DESKTOP
     103    help
     104      Support argument 'l' for long output.
     105      Adds fields PPID, RSS, START, TIME & TTY
     106
    105107config FEATURE_PS_TIME
    106108    bool "Enable time and elapsed time output"
    107109    default y
    108     depends on PS && DESKTOP && PLATFORM_LINUX #sysinfo()
     110    depends on PS && DESKTOP
     111    select PLATFORM_LINUX
    109112    help
    110113      Support -o time and -o etime output specifiers.
     
    138141      Configure kernel parameters at runtime.
    139142
    140 config TOP
    141     bool "top"
     143config FEATURE_SHOW_THREADS
     144    bool "Support for showing threads in ps/pstree/top"
    142145    default y
     146    depends on PS || TOP || PSTREE
    143147    help
    144       The top program provides a dynamic real-time view of a running
    145       system.
    146 
    147 config FEATURE_TOP_CPU_USAGE_PERCENTAGE
    148     bool "Show CPU per-process usage percentage"
    149     default y
    150     depends on TOP
    151     help
    152       Make top display CPU usage for each process.
    153       This adds about 2k.
    154 
    155 config FEATURE_TOP_CPU_GLOBAL_PERCENTS
    156     bool "Show CPU global usage percentage"
    157     default y
    158     depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE
    159     help
    160       Makes top display "CPU: NN% usr NN% sys..." line.
    161       This adds about 0.5k.
    162 
    163 config FEATURE_TOP_SMP_CPU
    164     bool "SMP CPU usage display ('c' key)"
    165     default y
    166     depends on FEATURE_TOP_CPU_GLOBAL_PERCENTS
    167     help
    168       Allow 'c' key to switch between individual/cumulative CPU stats
    169       This adds about 0.5k.
    170 
    171 config FEATURE_TOP_DECIMALS
    172     bool "Show 1/10th of a percent in CPU/mem statistics"
    173     default y
    174     depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE
    175     help
    176       Show 1/10th of a percent in CPU/mem statistics.
    177       This adds about 0.3k.
    178 
    179 config FEATURE_TOP_SMP_PROCESS
    180     bool "Show CPU process runs on ('j' field)"
    181     default y
    182     depends on TOP
    183     help
    184       Show CPU where process was last found running on.
    185       This is the 'j' field.
    186 
    187 config FEATURE_TOPMEM
    188     bool "Topmem command ('s' key)"
    189     default y
    190     depends on TOP
    191     help
    192       Enable 's' in top (gives lots of memory info).
    193 
    194 config FEATURE_SHOW_THREADS
    195     bool "Support for showing threads in ps/top"
    196     default y
    197     depends on PS || TOP
    198     help
    199       Enables ps -T option and 'h' command in top
    200 
    201 config UPTIME
    202     bool "uptime"
    203     default y
    204     depends on PLATFORM_LINUX #sysinfo()
    205     help
    206       uptime gives a one line display of the current time, how long
    207       the system has been running, how many users are currently logged
    208       on, and the system load averages for the past 1, 5, and 15 minutes.
     148      Enables the ps -T option, showing of threads in pstree,
     149      and 'h' command in top.
    209150
    210151config WATCH
  • branches/3.2/mindi-busybox/procps/Kbuild.src

    r2725 r3232  
    1212lib-$(CONFIG_KILL)  += kill.o
    1313lib-$(CONFIG_ASH)   += kill.o  # used for built-in kill by ash
    14 lib-$(CONFIG_NMETER)    += nmeter.o
    1514lib-$(CONFIG_PGREP) += pgrep.o
    1615lib-$(CONFIG_PKILL) += pgrep.o
  • branches/3.2/mindi-busybox/procps/free.c

    r2725 r3232  
    1010/* getopt not needed */
    1111
     12//usage:#define free_trivial_usage
     13//usage:       "" IF_DESKTOP("[-b/k/m/g]")
     14//usage:#define free_full_usage "\n\n"
     15//usage:       "Display the amount of free and used system memory"
     16//usage:
     17//usage:#define free_example_usage
     18//usage:       "$ free\n"
     19//usage:       "              total         used         free       shared      buffers\n"
     20//usage:       "  Mem:       257628       248724         8904        59644        93124\n"
     21//usage:       " Swap:       128516         8404       120112\n"
     22//usage:       "Total:       386144       257128       129016\n"
     23
    1224#include "libbb.h"
     25#ifdef __linux__
     26# include <sys/sysinfo.h>
     27#endif
    1328
    1429struct globals {
     
    2035# define G_unit_steps 10
    2136#endif
    22 };
     37} FIX_ALIASING;
    2338#define G (*(struct globals*)&bb_common_bufsiz1)
    2439#define INIT_G() do { } while (0)
  • branches/3.2/mindi-busybox/procps/fuser.c

    r2859 r3232  
    88 */
    99
     10//usage:#define fuser_trivial_usage
     11//usage:       "[OPTIONS] FILE or PORT/PROTO"
     12//usage:#define fuser_full_usage "\n\n"
     13//usage:       "Find processes which use FILEs or PORTs\n"
     14//usage:     "\n    -m  Find processes which use same fs as FILEs"
     15//usage:     "\n    -4,-6   Search only IPv4/IPv6 space"
     16//usage:     "\n    -s  Don't display PIDs"
     17//usage:     "\n    -k  Kill found processes"
     18//usage:     "\n    -SIGNAL Signal to send (default: KILL)"
     19
    1020#include "libbb.h"
    1121
     
    2737} inode_list;
    2838
    29 typedef struct pid_list {
    30     struct pid_list *next;
    31     pid_t pid;
    32 } pid_list;
    33 
    34 
    3539struct globals {
    36     pid_list *pid_list_head;
     40    int recursion_depth;
     41    pid_t mypid;
    3742    inode_list *inode_list_head;
    38 };
     43    smallint kill_failed;
     44    int killsig;
     45} FIX_ALIASING;
    3946#define G (*(struct globals*)&bb_common_bufsiz1)
    40 #define INIT_G() do { } while (0)
    41 
    42 
    43 static void add_pid(const pid_t pid)
    44 {
    45     pid_list **curr = &G.pid_list_head;
    46 
    47     while (*curr) {
    48         if ((*curr)->pid == pid)
    49             return;
    50         curr = &(*curr)->next;
    51     }
    52 
    53     *curr = xzalloc(sizeof(pid_list));
    54     (*curr)->pid = pid;
    55 }
     47#define INIT_G() do { \
     48    G.mypid = getpid(); \
     49    G.killsig = SIGKILL; \
     50} while (0)
    5651
    5752static void add_inode(const struct stat *st)
     
    7368}
    7469
    75 static void scan_proc_net(const char *path, unsigned port)
    76 {
    77     char line[MAX_LINE + 1];
    78     long long uint64_inode;
    79     unsigned tmp_port;
    80     FILE *f;
    81     struct stat st;
    82     int fd;
    83 
    84     /* find socket dev */
    85     st.st_dev = 0;
    86     fd = socket(AF_INET, SOCK_DGRAM, 0);
    87     if (fd >= 0) {
    88         fstat(fd, &st);
    89         close(fd);
    90     }
    91 
    92     f = fopen_for_read(path);
    93     if (!f)
    94         return;
    95 
    96     while (fgets(line, MAX_LINE, f)) {
    97         char addr[68];
    98         if (sscanf(line, "%*d: %64[0-9A-Fa-f]:%x %*x:%*x %*x %*x:%*x "
    99                 "%*x:%*x %*x %*d %*d %llu",
    100                 addr, &tmp_port, &uint64_inode) == 3
    101         ) {
    102             int len = strlen(addr);
    103             if (len == 8 && (option_mask32 & OPT_IP6))
    104                 continue;
    105             if (len > 8 && (option_mask32 & OPT_IP4))
    106                 continue;
    107             if (tmp_port == port) {
    108                 st.st_ino = uint64_inode;
    109                 add_inode(&st);
    110             }
    111         }
    112     }
    113     fclose(f);
    114 }
    115 
    116 static int search_dev_inode(const struct stat *st)
     70static smallint search_dev_inode(const struct stat *st)
    11771{
    11872    inode_list *ilist = G.inode_list_head;
     
    13084}
    13185
    132 static void scan_pid_maps(const char *fname, pid_t pid)
    133 {
    134     FILE *file;
    135     char line[MAX_LINE + 1];
    136     int major, minor;
     86enum {
     87    PROC_NET = 0,
     88    PROC_DIR,
     89    PROC_DIR_LINKS,
     90    PROC_SUBDIR_LINKS,
     91};
     92
     93static smallint scan_proc_net_or_maps(const char *path, unsigned port)
     94{
     95    FILE *f;
     96    char line[MAX_LINE + 1], addr[68];
     97    int major, minor, r;
    13798    long long uint64_inode;
    138     struct stat st;
    139 
    140     file = fopen_for_read(fname);
    141     if (!file)
    142         return;
    143 
    144     while (fgets(line, MAX_LINE, file)) {
    145         if (sscanf(line, "%*s %*s %*s %x:%x %llu", &major, &minor, &uint64_inode) != 3)
     99    unsigned tmp_port;
     100    smallint retval;
     101    struct stat statbuf;
     102    const char *fmt;
     103    void *fag, *sag;
     104
     105    f = fopen_for_read(path);
     106    if (!f)
     107        return 0;
     108
     109    if (G.recursion_depth == PROC_NET) {
     110        int fd;
     111
     112        /* find socket dev */
     113        statbuf.st_dev = 0;
     114        fd = socket(AF_INET, SOCK_DGRAM, 0);
     115        if (fd >= 0) {
     116            fstat(fd, &statbuf);
     117            close(fd);
     118        }
     119
     120        fmt = "%*d: %64[0-9A-Fa-f]:%x %*x:%*x %*x "
     121            "%*x:%*x %*x:%*x %*x %*d %*d %llu";
     122        fag = addr;
     123        sag = &tmp_port;
     124    } else {
     125        fmt = "%*s %*s %*s %x:%x %llu";
     126        fag = &major;
     127        sag = &minor;
     128    }
     129
     130    retval = 0;
     131    while (fgets(line, MAX_LINE, f)) {
     132        r = sscanf(line, fmt, fag, sag, &uint64_inode);
     133        if (r != 3)
    146134            continue;
    147         st.st_ino = uint64_inode;
    148         if (major == 0 && minor == 0 && st.st_ino == 0)
    149             continue;
    150         st.st_dev = makedev(major, minor);
    151         if (search_dev_inode(&st))
    152             add_pid(pid);
    153     }
    154     fclose(file);
    155 }
    156 
    157 static void scan_link(const char *lname, pid_t pid)
    158 {
    159     struct stat st;
    160 
    161     if (stat(lname, &st) >= 0) {
    162         if (search_dev_inode(&st))
    163             add_pid(pid);
    164     }
    165 }
    166 
    167 static void scan_dir_links(const char *dname, pid_t pid)
     135
     136        statbuf.st_ino = uint64_inode;
     137        if (G.recursion_depth == PROC_NET) {
     138            r = strlen(addr);
     139            if (r == 8 && (option_mask32 & OPT_IP6))
     140                continue;
     141            if (r > 8 && (option_mask32 & OPT_IP4))
     142                continue;
     143            if (tmp_port == port)
     144                add_inode(&statbuf);
     145        } else {
     146            if (major != 0 && minor != 0 && statbuf.st_ino != 0) {
     147                statbuf.st_dev = makedev(major, minor);
     148                retval = search_dev_inode(&statbuf);
     149                if (retval)
     150                    break;
     151            }
     152        }
     153    }
     154    fclose(f);
     155
     156    return retval;
     157}
     158
     159static smallint scan_recursive(const char *path)
    168160{
    169161    DIR *d;
    170     struct dirent *de;
    171     char *lname;
    172 
    173     d = opendir(dname);
    174     if (!d)
    175         return;
    176 
    177     while ((de = readdir(d)) != NULL) {
    178         lname = concat_subpath_file(dname, de->d_name);
    179         if (lname == NULL)
    180             continue;
    181         scan_link(lname, pid);
    182         free(lname);
     162    struct dirent *d_ent;
     163    smallint stop_scan;
     164    smallint retval;
     165
     166    d = opendir(path);
     167    if (d == NULL)
     168        return 0;
     169
     170    G.recursion_depth++;
     171    retval = 0;
     172    stop_scan = 0;
     173    while (!stop_scan && (d_ent = readdir(d)) != NULL) {
     174        struct stat statbuf;
     175        pid_t pid;
     176        char *subpath;
     177
     178        subpath = concat_subpath_file(path, d_ent->d_name);
     179        if (subpath == NULL)
     180            continue; /* . or .. */
     181
     182        switch (G.recursion_depth) {
     183        case PROC_DIR:
     184            pid = (pid_t)bb_strtou(d_ent->d_name, NULL, 10);
     185            if (errno != 0
     186             || pid == G.mypid
     187            /* "this PID doesn't use specified FILEs or PORT/PROTO": */
     188             || scan_recursive(subpath) == 0
     189            ) {
     190                break;
     191            }
     192            if (option_mask32 & OPT_KILL) {
     193                if (kill(pid, G.killsig) != 0) {
     194                    bb_perror_msg("kill pid %s", d_ent->d_name);
     195                    G.kill_failed = 1;
     196                }
     197            }
     198            if (!(option_mask32 & OPT_SILENT))
     199                printf("%s ", d_ent->d_name);
     200            retval = 1;
     201            break;
     202
     203        case PROC_DIR_LINKS:
     204            switch (
     205                index_in_substrings(
     206                    "cwd"  "\0" "exe"  "\0"
     207                    "root" "\0" "fd"   "\0"
     208                    "lib"  "\0" "mmap" "\0"
     209                    "maps" "\0",
     210                    d_ent->d_name
     211                )
     212            ) {
     213            enum {
     214                CWD_LINK,
     215                EXE_LINK,
     216                ROOT_LINK,
     217                FD_DIR_LINKS,
     218                LIB_DIR_LINKS,
     219                MMAP_DIR_LINKS,
     220                MAPS,
     221            };
     222            case CWD_LINK:
     223            case EXE_LINK:
     224            case ROOT_LINK:
     225                goto scan_link;
     226            case FD_DIR_LINKS:
     227            case LIB_DIR_LINKS:
     228            case MMAP_DIR_LINKS:
     229                stop_scan = scan_recursive(subpath);
     230                if (stop_scan)
     231                    retval = stop_scan;
     232                break;
     233            case MAPS:
     234                stop_scan = scan_proc_net_or_maps(subpath, 0);
     235                if (stop_scan)
     236                    retval = stop_scan;
     237            default:
     238                break;
     239            }
     240            break;
     241        case PROC_SUBDIR_LINKS:
     242  scan_link:
     243            if (stat(subpath, &statbuf) < 0)
     244                break;
     245            stop_scan = search_dev_inode(&statbuf);
     246            if (stop_scan)
     247                retval = stop_scan;
     248        default:
     249            break;
     250        }
     251        free(subpath);
    183252    }
    184253    closedir(d);
    185 }
    186 
    187 /* NB: does chdir internally */
    188 static void scan_proc_pids(void)
    189 {
    190     DIR *d;
    191     struct dirent *de;
    192     pid_t pid;
    193 
    194     xchdir("/proc");
    195     d = opendir("/proc");
    196     if (!d)
    197         return;
    198 
    199     while ((de = readdir(d)) != NULL) {
    200         pid = (pid_t)bb_strtou(de->d_name, NULL, 10);
    201         if (errno)
    202             continue;
    203         if (chdir(de->d_name) < 0)
    204             continue;
    205         scan_link("cwd", pid);
    206         scan_link("exe", pid);
    207         scan_link("root", pid);
    208 
    209         scan_dir_links("fd", pid);
    210         scan_dir_links("lib", pid);
    211         scan_dir_links("mmap", pid);
    212 
    213         scan_pid_maps("maps", pid);
    214         xchdir("/proc");
    215     }
    216     closedir(d);
     254    G.recursion_depth--;
     255    return retval;
    217256}
    218257
     
    220259int fuser_main(int argc UNUSED_PARAM, char **argv)
    221260{
    222     pid_list *plist;
    223     pid_t mypid;
    224261    char **pp;
    225     struct stat st;
    226     unsigned port;
    227     int opt;
    228     int exitcode;
    229     int killsig;
    230 /*
    231 fuser [OPTIONS] FILE or PORT/PROTO
    232 Find processes which use FILEs or PORTs
    233         -m      Find processes which use same fs as FILEs
    234         -4      Search only IPv4 space
    235         -6      Search only IPv6 space
    236         -s      Don't display PIDs
    237         -k      Kill found processes
    238         -SIGNAL Signal to send (default: KILL)
    239 */
     262
     263    INIT_G();
     264
    240265    /* Handle -SIGNAL. Oh my... */
    241     killsig = SIGKILL; /* yes, the default is not SIGTERM */
    242266    pp = argv;
    243267    while (*++pp) {
     268        int sig;
    244269        char *arg = *pp;
     270
    245271        if (arg[0] != '-')
    246272            continue;
     
    249275        if ((arg[1] == '4' || arg[1] == '6') && arg[2] == '\0')
    250276            continue; /* it's "-4" or "-6" */
    251         opt = get_signum(&arg[1]);
    252         if (opt < 0)
     277        sig = get_signum(&arg[1]);
     278        if (sig < 0)
    253279            continue;
    254280        /* "-SIGNAL" option found. Remove it and bail out */
    255         killsig = opt;
     281        G.killsig = sig;
    256282        do {
    257283            pp[0] = arg = pp[1];
     
    262288
    263289    opt_complementary = "-1"; /* at least one param */
    264     opt = getopt32(argv, OPTION_STRING);
     290    getopt32(argv, OPTION_STRING);
    265291    argv += optind;
    266292
     
    268294    while (*pp) {
    269295        /* parse net arg */
    270         char path[20], tproto[5];
    271         if (sscanf(*pp, "%u/%4s", &port, tproto) != 2)
    272             goto file;
    273         sprintf(path, "/proc/net/%s", tproto);
    274         if (access(path, R_OK) == 0) { /* PORT/PROTO */
    275             scan_proc_net(path, port);
    276         } else { /* FILE */
    277  file:
    278             xstat(*pp, &st);
    279             add_inode(&st);
     296        unsigned port;
     297        char path[sizeof("/proc/net/TCP6")];
     298
     299        strcpy(path, "/proc/net/");
     300        if (sscanf(*pp, "%u/%4s", &port, path + sizeof("/proc/net/")-1) == 2
     301         && access(path, R_OK) == 0
     302        ) {
     303            /* PORT/PROTO */
     304            scan_proc_net_or_maps(path, port);
     305        } else {
     306            /* FILE */
     307            struct stat statbuf;
     308            xstat(*pp, &statbuf);
     309            add_inode(&statbuf);
    280310        }
    281311        pp++;
    282312    }
    283313
    284     scan_proc_pids(); /* changes dir to "/proc" */
    285 
    286     mypid = getpid();
    287     plist = G.pid_list_head;
    288     while (1) {
    289         if (!plist)
    290             return EXIT_FAILURE;
    291         if (plist->pid != mypid)
    292             break;
    293         plist = plist->next;
    294     }
    295 
    296     exitcode = EXIT_SUCCESS;
    297     do {
    298         if (plist->pid != mypid) {
    299             if (opt & OPT_KILL) {
    300                 if (kill(plist->pid, killsig) != 0) {
    301                     bb_perror_msg("kill pid %u", (unsigned)plist->pid);
    302                     exitcode = EXIT_FAILURE;
    303                 }
    304             }
    305             if (!(opt & OPT_SILENT)) {
    306                 printf("%u ", (unsigned)plist->pid);
    307             }
    308         }
    309         plist = plist->next;
    310     } while (plist);
    311 
    312     if (!(opt & (OPT_SILENT))) {
    313         bb_putchar('\n');
    314     }
    315 
    316     return exitcode;
    317 }
     314    if (scan_recursive("/proc")) {
     315        if (!(option_mask32 & OPT_SILENT))
     316            bb_putchar('\n');
     317        return G.kill_failed;
     318    }
     319
     320    return EXIT_FAILURE;
     321}
  • branches/3.2/mindi-busybox/procps/iostat.c

    r2725 r3232  
    88 */
    99
    10 //applet:IF_IOSTAT(APPLET(iostat, _BB_DIR_BIN, _BB_SUID_DROP))
    11 
    12 //kbuild:lib-$(CONFIG_IOSTAT) += iostat.o
    13 
    1410//config:config IOSTAT
    1511//config:   bool "iostat"
     
    1814//config:     Report CPU and I/O statistics
    1915
     16//applet:IF_IOSTAT(APPLET(iostat, BB_DIR_BIN, BB_SUID_DROP))
     17
     18//kbuild:lib-$(CONFIG_IOSTAT) += iostat.o
     19
    2020#include "libbb.h"
    21 #include <sys/utsname.h>  /* Need struct utsname */
     21#include <sys/utsname.h>  /* struct utsname */
    2222
    2323//#define debug(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
     
    2525
    2626#define MAX_DEVICE_NAME 12
    27 #define CURRENT          0
    28 #define LAST             1
     27#define MAX_DEVICE_NAME_STR "12"
    2928
    3029#if 1
     
    4039#endif
    4140
    42 struct stats_cpu {
    43     cputime_t cpu_user;
    44     cputime_t cpu_nice;
    45     cputime_t cpu_system;
    46     cputime_t cpu_idle;
    47     cputime_t cpu_iowait;
    48     cputime_t cpu_steal;
    49     cputime_t cpu_irq;
    50     cputime_t cpu_softirq;
    51     cputime_t cpu_guest;
     41enum {
     42    STATS_CPU_USER,
     43    STATS_CPU_NICE,
     44    STATS_CPU_SYSTEM,
     45    STATS_CPU_IDLE,
     46    STATS_CPU_IOWAIT,
     47    STATS_CPU_IRQ,
     48    STATS_CPU_SOFTIRQ,
     49    STATS_CPU_STEAL,
     50    STATS_CPU_GUEST,
     51
     52    GLOBAL_UPTIME,
     53    SMP_UPTIME,
     54
     55    N_STATS_CPU,
    5256};
    5357
    54 struct stats_dev {
    55     char dname[MAX_DEVICE_NAME];
     58typedef struct {
     59    cputime_t vector[N_STATS_CPU];
     60} stats_cpu_t;
     61
     62typedef struct {
     63    stats_cpu_t *prev;
     64    stats_cpu_t *curr;
     65    cputime_t itv;
     66} stats_cpu_pair_t;
     67
     68typedef struct {
    5669    unsigned long long rd_sectors;
    5770    unsigned long long wr_sectors;
    5871    unsigned long rd_ops;
    5972    unsigned long wr_ops;
    60 };
    61 
    62 /* List of devices entered on the command line */
    63 struct device_list {
    64     char dname[MAX_DEVICE_NAME];
    65 };
     73} stats_dev_data_t;
     74
     75typedef struct stats_dev {
     76    struct stats_dev *next;
     77    char dname[MAX_DEVICE_NAME + 1];
     78    stats_dev_data_t prev_data;
     79    stats_dev_data_t curr_data;
     80} stats_dev_t;
    6681
    6782/* Globals. Sort by size and access frequency. */
    6883struct globals {
    6984    smallint show_all;
    70     unsigned devlist_i;             /* Index to the list of devices */
    7185    unsigned total_cpus;            /* Number of CPUs */
    7286    unsigned clk_tck;               /* Number of clock ticks per second */
    73     struct device_list *dlist;
    74     struct stats_dev *saved_stats_dev;
     87    llist_t *dev_name_list;         /* List of devices entered on the command line */
     88    stats_dev_t *stats_dev_list;
    7589    struct tm tmtime;
     90    struct {
     91        const char *str;
     92        unsigned div;
     93    } unit;
    7694};
    7795#define G (*ptr_to_globals)
    7896#define INIT_G() do { \
    7997    SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
     98    G.unit.str = "Blk"; \
     99    G.unit.div = 1; \
    80100} while (0)
    81101
     
    102122static void print_header(void)
    103123{
    104     char buf[16];
     124    char buf[32];
    105125    struct utsname uts;
    106126
    107     if (uname(&uts) < 0)
    108         bb_perror_msg_and_die("uname");
    109 
     127    uname(&uts); /* never fails */
     128
     129    /* Date representation for the current locale */
    110130    strftime(buf, sizeof(buf), "%x", &G.tmtime);
    111131
    112     printf("%s %s (%s) \t%s \t_%s_\t(%d CPU)\n\n",
     132    printf("%s %s (%s) \t%s \t_%s_\t(%u CPU)\n\n",
    113133            uts.sysname, uts.release, uts.nodename,
    114134            buf, uts.machine, G.total_cpus);
     
    124144static void print_timestamp(void)
    125145{
    126     char buf[20];
     146    char buf[64];
     147    /* %x: date representation for the current locale */
     148    /* %X: time representation for the current locale */
    127149    strftime(buf, sizeof(buf), "%x %X", &G.tmtime);
    128150    printf("%s\n", buf);
    129151}
    130152
     153static cputime_t get_smp_uptime(void)
     154{
     155    FILE *fp;
     156    unsigned long sec, dec;
     157
     158    fp = xfopen_for_read("/proc/uptime");
     159
     160    if (fscanf(fp, "%lu.%lu", &sec, &dec) != 2)
     161        bb_error_msg_and_die("can't read '%s'", "/proc/uptime");
     162
     163    fclose(fp);
     164
     165    return (cputime_t)sec * G.clk_tck + dec * G.clk_tck / 100;
     166}
     167
    131168/* Fetch CPU statistics from /proc/stat */
    132 static void get_cpu_statistics(struct stats_cpu *sc)
     169static void get_cpu_statistics(stats_cpu_t *sc)
    133170{
    134171    FILE *fp;
     
    140177
    141178    while (fgets(buf, sizeof(buf), fp)) {
    142         /* Does the line starts with "cpu "? */
    143         if (starts_with_cpu(buf) && buf[3] == ' ') {
    144             sscanf(buf + 4 + 1,
    145                 "%"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u %"
    146                 FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u",
    147                 &sc->cpu_user, &sc->cpu_nice, &sc->cpu_system,
    148                 &sc->cpu_idle, &sc->cpu_iowait, &sc->cpu_irq,
    149                 &sc->cpu_softirq, &sc->cpu_steal, &sc->cpu_guest);
    150         }
     179        int i;
     180        char *ibuf;
     181
     182        /* Does the line start with "cpu "? */
     183        if (!starts_with_cpu(buf) || buf[3] != ' ') {
     184            continue;
     185        }
     186        ibuf = buf + 4;
     187        for (i = STATS_CPU_USER; i <= STATS_CPU_GUEST; i++) {
     188            ibuf = skip_whitespace(ibuf);
     189            sscanf(ibuf, "%"FMT_DATA"u", &sc->vector[i]);
     190            if (i != STATS_CPU_GUEST) {
     191                sc->vector[GLOBAL_UPTIME] += sc->vector[i];
     192            }
     193            ibuf = skip_non_whitespace(ibuf);
     194        }
     195        break;
     196    }
     197
     198    if (this_is_smp()) {
     199        sc->vector[SMP_UPTIME] = get_smp_uptime();
    151200    }
    152201
    153202    fclose(fp);
    154 }
    155 
    156 static cputime_t get_smp_uptime(void)
    157 {
    158     FILE *fp;
    159     char buf[sizeof(long)*3 * 2 + 4];
    160     unsigned long sec, dec;
    161 
    162     fp = xfopen_for_read("/proc/uptime");
    163 
    164     if (fgets(buf, sizeof(buf), fp))
    165         if (sscanf(buf, "%lu.%lu", &sec, &dec) != 2)
    166             bb_error_msg_and_die("can't read /proc/uptime");
    167 
    168     fclose(fp);
    169 
    170     return (cputime_t)sec * G.clk_tck + dec * G.clk_tck / 100;
    171 }
    172 
    173 /*
    174  * Obtain current uptime in jiffies.
    175  * Uptime is sum of individual CPUs' uptimes.
    176  */
    177 static cputime_t get_uptime(const struct stats_cpu *sc)
    178 {
    179     /* NB: Don't include cpu_guest, it is already in cpu_user */
    180     return sc->cpu_user + sc->cpu_nice + sc->cpu_system + sc->cpu_idle +
    181         + sc->cpu_iowait + sc->cpu_irq + sc->cpu_steal + sc->cpu_softirq;
    182203}
    183204
     
    220241}
    221242
    222 static void print_stats_cpu_struct(const struct stats_cpu *p,
    223         const struct stats_cpu *c, cputime_t itv)
    224 {
    225     printf("         %6.2f  %6.2f  %6.2f  %6.2f  %6.2f  %6.2f\n",
    226         percent_value(p->cpu_user   , c->cpu_user   , itv),
    227         percent_value(p->cpu_nice   , c->cpu_nice   , itv),
    228         percent_value(p->cpu_system + p->cpu_softirq + p->cpu_irq,
    229             c->cpu_system + c->cpu_softirq + c->cpu_irq, itv),
    230         percent_value(p->cpu_iowait , c->cpu_iowait , itv),
    231         percent_value(p->cpu_steal  , c->cpu_steal  , itv),
    232         percent_value(p->cpu_idle   , c->cpu_idle   , itv)
     243static void print_stats_cpu_struct(stats_cpu_pair_t *stats)
     244{
     245    cputime_t *p = stats->prev->vector;
     246    cputime_t *c = stats->curr->vector;
     247    printf("        %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f\n",
     248        percent_value(p[STATS_CPU_USER]  , c[STATS_CPU_USER]  , stats->itv),
     249        percent_value(p[STATS_CPU_NICE]  , c[STATS_CPU_NICE]  , stats->itv),
     250        percent_value(p[STATS_CPU_SYSTEM] + p[STATS_CPU_SOFTIRQ] + p[STATS_CPU_IRQ],
     251            c[STATS_CPU_SYSTEM] + c[STATS_CPU_SOFTIRQ] + c[STATS_CPU_IRQ], stats->itv),
     252        percent_value(p[STATS_CPU_IOWAIT], c[STATS_CPU_IOWAIT], stats->itv),
     253        percent_value(p[STATS_CPU_STEAL] , c[STATS_CPU_STEAL] , stats->itv),
     254        percent_value(p[STATS_CPU_IDLE]  , c[STATS_CPU_IDLE]  , stats->itv)
    233255    );
    234256}
    235257
    236 static void print_stats_dev_struct(const struct stats_dev *p,
    237         const struct stats_dev *c, cputime_t itv)
    238 {
    239     int unit = 1;
    240 
    241     if (option_mask32 & OPT_k)
    242         unit = 2;
    243     else if (option_mask32 & OPT_m)
    244         unit = 2048;
    245 
     258static void cpu_report(stats_cpu_pair_t *stats)
     259{
     260    /* Always print a header */
     261    puts("avg-cpu:  %user   %nice %system %iowait  %steal   %idle");
     262
     263    /* Print current statistics */
     264    print_stats_cpu_struct(stats);
     265}
     266
     267static void print_stats_dev_struct(stats_dev_t *stats_dev, cputime_t itv)
     268{
     269    stats_dev_data_t *p = &stats_dev->prev_data;
     270    stats_dev_data_t *c = &stats_dev->curr_data;
    246271    if (option_mask32 & OPT_z)
    247272        if (p->rd_ops == c->rd_ops && p->wr_ops == c->wr_ops)
    248273            return;
    249274
    250     printf("%-13s", c->dname);
    251     printf(" %8.2f %12.2f %12.2f %10llu %10llu \n",
    252         percent_value(p->rd_ops + p->wr_ops ,
    253         /**/          c->rd_ops + c->wr_ops , itv),
    254         percent_value(p->rd_sectors, c->rd_sectors, itv) / unit,
    255         percent_value(p->wr_sectors, c->wr_sectors, itv) / unit,
    256         (c->rd_sectors - p->rd_sectors) / unit,
    257         (c->wr_sectors - p->wr_sectors) / unit);
    258 }
    259 
    260 static void cpu_report(const struct stats_cpu *last,
    261         const struct stats_cpu *cur,
    262         cputime_t itv)
    263 {
    264     /* Always print a header */
    265     puts("avg-cpu:  %user   %nice %system %iowait  %steal   %idle");
    266 
    267     /* Print current statistics */
    268     print_stats_cpu_struct(last, cur, itv);
     275    printf("%-13s %8.2f %12.2f %12.2f %10llu %10llu\n",
     276        stats_dev->dname,
     277        percent_value(p->rd_ops + p->wr_ops, c->rd_ops + c->wr_ops, itv),
     278        percent_value(p->rd_sectors, c->rd_sectors, itv) / G.unit.div,
     279        percent_value(p->wr_sectors, c->wr_sectors, itv) / G.unit.div,
     280        (c->rd_sectors - p->rd_sectors) / G.unit.div,
     281        (c->wr_sectors - p->wr_sectors) / G.unit.div
     282    );
    269283}
    270284
    271285static void print_devstat_header(void)
    272286{
    273     printf("Device:            tps");
    274 
    275     if (option_mask32 & OPT_m)
    276         puts("    MB_read/s    MB_wrtn/s    MB_read    MB_wrtn");
    277     else if (option_mask32 & OPT_k)
    278         puts("    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn");
    279     else
    280         puts("   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn");
     287    printf("Device:%15s%6s%s/s%6s%s/s%6s%s%6s%s\n",
     288        "tps",
     289        G.unit.str, "_read", G.unit.str, "_wrtn",
     290        G.unit.str, "_read", G.unit.str, "_wrtn"
     291    );
    281292}
    282293
     
    290301}
    291302
    292 /*
    293  * Return number of numbers on cmdline.
    294  * Reasonable values are only 0 (no interval/count specified),
    295  * 1 (interval specified) and 2 (both interval and count specified)
    296  */
    297 static int numbers_on_cmdline(int argc, char *argv[])
    298 {
    299     int sum = 0;
    300 
    301     if (isdigit(argv[argc-1][0]))
    302         sum++;
    303     if (argc > 2 && isdigit(argv[argc-2][0]))
    304         sum++;
    305 
    306     return sum;
    307 }
    308 
    309 static int is_dev_in_dlist(const char *dev)
    310 {
    311     int i;
    312 
    313     /* Go through the device list */
    314     for (i = 0; i < G.devlist_i; i++)
    315         if (strcmp(G.dlist[i].dname, dev) == 0)
    316             /* Found a match */
    317             return 1;
    318 
    319     /* No match found */
    320     return 0;
     303static stats_dev_t *stats_dev_find_or_new(const char *dev_name)
     304{
     305    stats_dev_t **curr = &G.stats_dev_list;
     306
     307    while (*curr != NULL) {
     308        if (strcmp((*curr)->dname, dev_name) == 0)
     309            return *curr;
     310        curr = &(*curr)->next;
     311    }
     312
     313    *curr = xzalloc(sizeof(stats_dev_t));
     314    strncpy((*curr)->dname, dev_name, MAX_DEVICE_NAME);
     315    return *curr;
     316}
     317
     318static void stats_dev_free(stats_dev_t *stats_dev)
     319{
     320    if (stats_dev) {
     321        stats_dev_free(stats_dev->next);
     322        free(stats_dev);
     323    }
    321324}
    322325
    323326static void do_disk_statistics(cputime_t itv)
    324327{
     328    char buf[128];
     329    char dev_name[MAX_DEVICE_NAME + 1];
     330    unsigned long long rd_sec_or_dummy;
     331    unsigned long long wr_sec_or_dummy;
     332    stats_dev_data_t *curr_data;
     333    stats_dev_t *stats_dev;
    325334    FILE *fp;
    326335    int rc;
    327     int i = 0;
    328     char buf[128];
    329     unsigned major, minor;
    330     unsigned long wr_ops, dummy; /* %*lu for suppress the conversion wouldn't work */
    331     unsigned long long rd_sec_or_wr_ops;
    332     unsigned long long rd_sec_or_dummy, wr_sec_or_dummy, wr_sec;
    333     struct stats_dev sd;
    334336
    335337    fp = xfopen_for_read("/proc/diskstats");
    336 
    337338    /* Read and possibly print stats from /proc/diskstats */
    338339    while (fgets(buf, sizeof(buf), fp)) {
    339         rc = sscanf(buf, "%u %u %s %lu %llu %llu %llu %lu %lu %llu %lu %lu %lu %lu",
    340             &major, &minor, sd.dname, &sd.rd_ops,
    341             &rd_sec_or_dummy, &rd_sec_or_wr_ops, &wr_sec_or_dummy,
    342             &wr_ops, &dummy, &wr_sec, &dummy, &dummy, &dummy, &dummy);
    343 
    344         switch (rc) {
    345         case 14:
    346             sd.wr_ops = wr_ops;
    347             sd.rd_sectors = rd_sec_or_wr_ops;
    348             sd.wr_sectors = wr_sec;
    349             break;
    350         case 7:
    351             sd.rd_sectors = rd_sec_or_dummy;
    352             sd.wr_ops = (unsigned long)rd_sec_or_wr_ops;
    353             sd.wr_sectors = wr_sec_or_dummy;
    354             break;
    355         default:
    356             break;
    357         }
    358 
    359         if (!G.devlist_i && !is_partition(sd.dname)) {
    360             /* User didn't specify device */
    361             if (!G.show_all && !sd.rd_ops && !sd.wr_ops) {
    362                 /* Don't print unused device */
     340        sscanf(buf, "%*s %*s %"MAX_DEVICE_NAME_STR"s", dev_name);
     341        if (G.dev_name_list) {
     342            /* Is device name in list? */
     343            if (!llist_find_str(G.dev_name_list, dev_name))
    363344                continue;
    364             }
    365             print_stats_dev_struct(&G.saved_stats_dev[i], &sd, itv);
    366             G.saved_stats_dev[i] = sd;
    367             i++;
    368         } else {
    369             /* Is device in device list? */
    370             if (is_dev_in_dlist(sd.dname)) {
    371                 /* Print current statistics */
    372                 print_stats_dev_struct(&G.saved_stats_dev[i], &sd, itv);
    373                 G.saved_stats_dev[i] = sd;
    374                 i++;
    375             } else
    376                 continue;
    377         }
     345        } else if (is_partition(dev_name)) {
     346            continue;
     347        }
     348
     349        stats_dev = stats_dev_find_or_new(dev_name);
     350        curr_data = &stats_dev->curr_data;
     351
     352        rc = sscanf(buf, "%*s %*s %*s %lu %llu %llu %llu %lu %*s %llu",
     353            &curr_data->rd_ops,
     354            &rd_sec_or_dummy,
     355            &curr_data->rd_sectors,
     356            &wr_sec_or_dummy,
     357            &curr_data->wr_ops,
     358            &curr_data->wr_sectors);
     359        if (rc != 6) {
     360            curr_data->rd_sectors = rd_sec_or_dummy;
     361            curr_data->wr_sectors = wr_sec_or_dummy;
     362            //curr_data->rd_ops = ;
     363            curr_data->wr_ops = (unsigned long)curr_data->rd_sectors;
     364        }
     365
     366        if (!G.dev_name_list /* User didn't specify device */
     367         && !G.show_all
     368         && curr_data->rd_ops == 0
     369         && curr_data->wr_ops == 0
     370        ) {
     371            /* Don't print unused device */
     372            continue;
     373        }
     374
     375        /* Print current statistics */
     376        print_stats_dev_struct(stats_dev, itv);
     377        stats_dev->prev_data = *curr_data;
    378378    }
    379379
     
    388388    /* Fetch current disk statistics */
    389389    do_disk_statistics(itv);
    390 }
    391 
    392 static void save_to_devlist(const char *dname)
    393 {
    394     int i;
    395     struct device_list *tmp = G.dlist;
    396 
    397     if (strncmp(dname, "/dev/", 5) == 0)
    398         /* We'll ignore prefix '/dev/' */
    399         dname += 5;
    400 
    401     /* Go through the list */
    402     for (i = 0; i < G.devlist_i; i++, tmp++)
    403         if (strcmp(tmp->dname, dname) == 0)
    404             /* Already in the list */
    405             return;
    406 
    407     /* Add device name to the list */
    408     strncpy(tmp->dname, dname, MAX_DEVICE_NAME - 1);
    409 
    410     /* Update device list index */
    411     G.devlist_i++;
    412 }
    413 
    414 static unsigned get_number_of_devices(void)
    415 {
    416     FILE *fp;
    417     char buf[128];
    418     int rv;
    419     unsigned n = 0;
    420     unsigned long rd_ops, wr_ops;
    421     char dname[MAX_DEVICE_NAME];
    422 
    423     fp = xfopen_for_read("/proc/diskstats");
    424 
    425     while (fgets(buf, sizeof(buf), fp)) {
    426         rv = sscanf(buf, "%*d %*d %s %lu %*u %*u %*u %lu",
    427                 dname, &rd_ops, &wr_ops);
    428         if (rv == 2 || is_partition(dname))
    429             /* A partition */
    430             continue;
    431         if (!rd_ops && !wr_ops) {
    432             /* Unused device */
    433             if (!G.show_all)
    434                 continue;
    435         }
    436         n++;
    437     }
    438 
    439     fclose(fp);
    440     return n;
    441 }
    442 
    443 static int number_of_ALL_on_cmdline(char **argv)
    444 {
    445     int alls = 0;
    446 
    447     /* Iterate over cmd line arguments, count "ALL" */
    448     while (*argv)
    449         if (strcmp(*argv++, "ALL") == 0)
    450             alls++;
    451 
    452     return alls;
    453390}
    454391
     
    457394//usage:#define iostat_full_usage "\n\n"
    458395//usage:       "Report CPU and I/O statistics\n"
    459 //usage:     "\nOptions:"
    460396//usage:     "\n    -c  Show CPU utilization"
    461397//usage:     "\n    -d  Show device utilization"
     
    466402
    467403int iostat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    468 int iostat_main(int argc, char **argv)
    469 {
    470     int opt, dev_num;
    471     unsigned interval = 0;
     404int iostat_main(int argc UNUSED_PARAM, char **argv)
     405{
     406    int opt;
     407    unsigned interval;
    472408    int count;
    473     cputime_t global_uptime[2] = { 0 };
    474     cputime_t smp_uptime[2] = { 0 };
    475     cputime_t itv;
    476     struct stats_cpu stats_cur, stats_last;
     409    stats_cpu_t stats_data[2];
     410    smallint current_stats;
    477411
    478412    INIT_G();
    479413
    480     memset(&stats_last, 0, sizeof(stats_last));
     414    memset(&stats_data, 0, sizeof(stats_data));
    481415
    482416    /* Get number of clock ticks per sec */
     
    497431
    498432    argv += optind;
    499     argc -= optind;
    500 
    501     dev_num = argc - numbers_on_cmdline(argc, argv);
    502     /* We don't want to allocate space for 'ALL' */
    503     dev_num -= number_of_ALL_on_cmdline(argv);
    504     if (dev_num > 0)
    505         /* Make space for device list */
    506         G.dlist = xzalloc(sizeof(G.dlist[0]) * dev_num);
    507433
    508434    /* Store device names into device list */
    509435    while (*argv && !isdigit(*argv[0])) {
    510         if (strcmp(*argv, "ALL") != 0)
     436        if (strcmp(*argv, "ALL") != 0) {
    511437            /* If not ALL, save device name */
    512             save_to_devlist(*argv);
    513         else
     438            char *dev_name = skip_dev_pfx(*argv);
     439            if (!llist_find_str(G.dev_name_list, dev_name)) {
     440                llist_add_to(&G.dev_name_list, dev_name);
     441            }
     442        } else {
    514443            G.show_all = 1;
     444        }
    515445        argv++;
    516446    }
    517447
     448    interval = 0;
    518449    count = 1;
    519450    if (*argv) {
     
    527458    }
    528459
    529     /* Allocate space for device stats */
    530     if (opt & OPT_d) {
    531         G.saved_stats_dev = xzalloc(sizeof(G.saved_stats_dev[0]) *
    532                 (dev_num ? dev_num : get_number_of_devices())
    533         );
    534     }
     460    if (opt & OPT_m) {
     461        G.unit.str = " MB";
     462        G.unit.div = 2048;
     463    }
     464
     465    if (opt & OPT_k) {
     466        G.unit.str = " kB";
     467        G.unit.div = 2;
     468    }
     469
     470    get_localtime(&G.tmtime);
    535471
    536472    /* Display header */
    537473    print_header();
    538474
     475    current_stats = 0;
    539476    /* Main loop */
    540477    for (;;) {
     478        stats_cpu_pair_t stats;
     479
     480        stats.prev = &stats_data[current_stats ^ 1];
     481        stats.curr = &stats_data[current_stats];
     482
    541483        /* Fill the time structure */
    542484        get_localtime(&G.tmtime);
    543485
    544486        /* Fetch current CPU statistics */
    545         get_cpu_statistics(&stats_cur);
    546 
    547         /* Fetch current uptime */
    548         global_uptime[CURRENT] = get_uptime(&stats_cur);
     487        get_cpu_statistics(stats.curr);
    549488
    550489        /* Get interval */
    551         itv = get_interval(global_uptime[LAST], global_uptime[CURRENT]);
     490        stats.itv = get_interval(
     491            stats.prev->vector[GLOBAL_UPTIME],
     492            stats.curr->vector[GLOBAL_UPTIME]
     493        );
    552494
    553495        if (opt & OPT_t)
     
    555497
    556498        if (opt & OPT_c) {
    557             cpu_report(&stats_last, &stats_cur, itv);
     499            cpu_report(&stats);
    558500            if (opt & OPT_d)
    559501                /* Separate outputs by a newline */
     
    563505        if (opt & OPT_d) {
    564506            if (this_is_smp()) {
    565                 smp_uptime[CURRENT] = get_smp_uptime();
    566                 itv = get_interval(smp_uptime[LAST], smp_uptime[CURRENT]);
    567                 smp_uptime[LAST] = smp_uptime[CURRENT];
     507                stats.itv = get_interval(
     508                    stats.prev->vector[SMP_UPTIME],
     509                    stats.curr->vector[SMP_UPTIME]
     510                );
    568511            }
    569             dev_report(itv);
    570         }
     512            dev_report(stats.itv);
     513        }
     514
     515        bb_putchar('\n');
    571516
    572517        if (count > 0) {
     
    575520        }
    576521
    577         /* Backup current stats */
    578         global_uptime[LAST] = global_uptime[CURRENT];
    579         stats_last = stats_cur;
    580 
    581         bb_putchar('\n');
     522        /* Swap stats */
     523        current_stats ^= 1;
     524
    582525        sleep(interval);
    583526    }
    584527
    585     bb_putchar('\n');
    586 
    587528    if (ENABLE_FEATURE_CLEAN_UP) {
     529        llist_free(G.dev_name_list, NULL);
     530        stats_dev_free(G.stats_dev_list);
    588531        free(&G);
    589         free(G.dlist);
    590         free(G.saved_stats_dev);
    591532    }
    592533
  • branches/3.2/mindi-busybox/procps/kill.c

    r2725 r3232  
    88 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    99 */
     10
     11//usage:#define kill_trivial_usage
     12//usage:       "[-l] [-SIG] PID..."
     13//usage:#define kill_full_usage "\n\n"
     14//usage:       "Send a signal (default: TERM) to given PIDs\n"
     15//usage:     "\n    -l  List all signal names and numbers"
     16/* //usage:  "\n    -s SIG  Yet another way of specifying SIG" */
     17//usage:
     18//usage:#define kill_example_usage
     19//usage:       "$ ps | grep apache\n"
     20//usage:       "252 root     root     S [apache]\n"
     21//usage:       "263 www-data www-data S [apache]\n"
     22//usage:       "264 www-data www-data S [apache]\n"
     23//usage:       "265 www-data www-data S [apache]\n"
     24//usage:       "266 www-data www-data S [apache]\n"
     25//usage:       "267 www-data www-data S [apache]\n"
     26//usage:       "$ kill 252\n"
     27//usage:
     28//usage:#define killall_trivial_usage
     29//usage:       "[-l] [-q] [-SIG] PROCESS_NAME..."
     30//usage:#define killall_full_usage "\n\n"
     31//usage:       "Send a signal (default: TERM) to given processes\n"
     32//usage:     "\n    -l  List all signal names and numbers"
     33/* //usage:  "\n    -s SIG  Yet another way of specifying SIG" */
     34//usage:     "\n    -q  Don't complain if no processes were killed"
     35//usage:
     36//usage:#define killall_example_usage
     37//usage:       "$ killall apache\n"
     38//usage:
     39//usage:#define killall5_trivial_usage
     40//usage:       "[-l] [-SIG] [-o PID]..."
     41//usage:#define killall5_full_usage "\n\n"
     42//usage:       "Send a signal (default: TERM) to all processes outside current session\n"
     43//usage:     "\n    -l  List all signal names and numbers"
     44//usage:     "\n    -o PID  Don't signal this PID"
     45/* //usage:  "\n    -s SIG  Yet another way of specifying SIG" */
    1046
    1147#include "libbb.h"
     
    128164        sid = getsid(pid);
    129165        /* Stop all processes */
    130         kill(-1, SIGSTOP);
     166        if (signo != SIGSTOP && signo != SIGCONT)
     167            kill(-1, SIGSTOP);
    131168        /* Signal all processes except those in our session */
    132         while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID))) {
     169        while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID)) != NULL) {
    133170            int i;
    134171
    135172            if (p->sid == (unsigned)sid
    136173             || p->pid == (unsigned)pid
    137              || p->pid == 1)
     174             || p->pid == 1
     175            ) {
    138176                continue;
     177            }
    139178
    140179            /* All remaining args must be -o PID options.
     
    166205 resume:
    167206        /* And let them continue */
    168         kill(-1, SIGCONT);
     207        if (signo != SIGSTOP && signo != SIGCONT)
     208            kill(-1, SIGCONT);
    169209        return ret;
    170210    }
     
    207247    /* Looks like they want to do a kill. Do that */
    208248    while (arg) {
    209         /* Support shell 'space' trick */
    210         if (arg[0] == ' ')
    211             arg++;
     249#if ENABLE_ASH || ENABLE_HUSH
     250        /*
     251         * We need to support shell's "hack formats" of
     252         * " -PRGP_ID" (yes, with a leading space)
     253         * and " PID1 PID2 PID3" (with degenerate case "")
     254         */
     255        while (*arg != '\0') {
     256            char *end;
     257            if (*arg == ' ')
     258                arg++;
     259            pid = bb_strtoi(arg, &end, 10);
     260            if (errno && (errno != EINVAL || *end != ' ')) {
     261                bb_error_msg("invalid number '%s'", arg);
     262                errors++;
     263                break;
     264            }
     265            if (kill(pid, signo) != 0) {
     266                bb_perror_msg("can't kill pid %d", (int)pid);
     267                errors++;
     268            }
     269            arg = end; /* can only point to ' ' or '\0' now */
     270        }
     271#else
    212272        pid = bb_strtoi(arg, NULL, 10);
    213273        if (errno) {
     
    218278            errors++;
    219279        }
     280#endif
    220281        arg = *++argv;
    221282    }
  • branches/3.2/mindi-busybox/procps/mpstat.c

    r2725 r3232  
    88 */
    99
    10 //applet:IF_MPSTAT(APPLET(mpstat, _BB_DIR_BIN, _BB_SUID_DROP))
     10//applet:IF_MPSTAT(APPLET(mpstat, BB_DIR_BIN, BB_SUID_DROP))
    1111
    1212//kbuild:lib-$(CONFIG_MPSTAT) += mpstat.o
     
    3737 * anything smaller than 10 chars looks ugly for /proc/softirqs stats.
    3838 */
    39 #define INTRATE_SCRWIDTH   10
     39#define INTRATE_SCRWIDTH      10
    4040#define INTRATE_SCRWIDTH_STR "10"
    4141
    4242/* System files */
    43 #define SYSFS_DEVCPU      "/sys/devices/system/cpu"
    4443#define PROCFS_STAT       "/proc/stat"
    4544#define PROCFS_INTERRUPTS "/proc/interrupts"
     
    846845//usage:#define mpstat_full_usage "\n\n"
    847846//usage:       "Per-processor statistics\n"
    848 //usage:     "\nOptions:"
    849847//usage:     "\n    -A          Same as -I ALL -u -P ALL"
    850848//usage:     "\n    -I SUM|CPU|ALL|SCPU Report interrupt statistics"
  • branches/3.2/mindi-busybox/procps/nmeter.c

    r2725 r3232  
    66 * Contact me: vda.linux@googlemail.com
    77 */
     8
     9//config:config NMETER
     10//config:   bool "nmeter"
     11//config:   default y
     12//config:   help
     13//config:     Prints selected system stats continuously, one line per update.
     14
     15//applet:IF_NMETER(APPLET(nmeter, BB_DIR_USR_BIN, BB_SUID_DROP))
     16
     17//kbuild:lib-$(CONFIG_NMETER) += nmeter.o
     18
     19//usage:#define nmeter_trivial_usage
     20//usage:       "[-d MSEC] FORMAT_STRING"
     21//usage:#define nmeter_full_usage "\n\n"
     22//usage:       "Monitor system in real time"
     23//usage:     "\n"
     24//usage:     "\n -d MSEC    Milliseconds between updates (default:1000)"
     25//usage:     "\n"
     26//usage:     "\nFormat specifiers:"
     27//usage:     "\n %Nc or %[cN]   CPU. N - bar size (default:10)"
     28//usage:     "\n        (displays: S:system U:user N:niced D:iowait I:irq i:softirq)"
     29//usage:     "\n %[nINTERFACE]  Network INTERFACE"
     30//usage:     "\n %m     Allocated memory"
     31//usage:     "\n %[mf]      Free memory"
     32//usage:     "\n %[mt]      Total memory"
     33//usage:     "\n %s     Allocated swap"
     34//usage:     "\n %f     Number of used file descriptors"
     35//usage:     "\n %Ni        Total/specific IRQ rate"
     36//usage:     "\n %x     Context switch rate"
     37//usage:     "\n %p     Forks"
     38//usage:     "\n %[pn]      # of processes"
     39//usage:     "\n %b     Block io"
     40//usage:     "\n %Nt        Time (with N decimal points)"
     41//usage:     "\n %r     Print <cr> instead of <lf> at EOL"
    842
    943//TODO:
     
    238272
    239273// Parses /proc/diskstats
    240 //   1  2 3   4  5        6(rd)  7      8     9     10(wr) 11     12 13     14
     274//   1  2 3   4     5     6(rd)  7      8     9     10(wr) 11     12 13     14
    241275//   3  0 hda 51292 14441 841783 926052 25717 79650 843256 3029804 0 148459 3956933
    242276//   3  1 hda1 0 0 0 0 <- ignore if only 4 fields
     277// Linux 3.0 (maybe earlier) started printing full stats for hda1 too.
     278// Had to add code which skips such devices.
    243279static int rdval_diskstats(const char* p, ullong *vec)
    244280{
    245     ullong rd = rd; // for compiler
    246     int indexline = 0;
     281    char devname[32];
     282    unsigned devname_len = 0;
     283    int value_idx = 0;
     284
    247285    vec[0] = 0;
    248286    vec[1] = 0;
    249287    while (1) {
    250         indexline++;
    251         while (*p == ' ' || *p == '\t') p++;
    252         if (*p == '\0') break;
     288        value_idx++;
     289        while (*p == ' ' || *p == '\t')
     290            p++;
     291        if (*p == '\0')
     292            break;
    253293        if (*p == '\n') {
    254             indexline = 0;
     294            value_idx = 0;
    255295            p++;
    256296            continue;
    257297        }
    258         if (indexline == 6) {
    259             rd = strtoull(p, NULL, 10);
    260         } else if (indexline == 10) {
    261             vec[0] += rd;  // TODO: *sectorsize (don't know how to find out sectorsize)
     298        if (value_idx == 3) {
     299            char *end = strchrnul(p, ' ');
     300            /* If this a hda1-like device (same prefix as last one + digit)? */
     301            if (devname_len && strncmp(devname, p, devname_len) == 0 && isdigit(p[devname_len])) {
     302                p = end;
     303                goto skip_line; /* skip entire line */
     304            }
     305            /* It is not. Remember the name for future checks */
     306            devname_len = end - p;
     307            if (devname_len > sizeof(devname)-1)
     308                devname_len = sizeof(devname)-1;
     309            strncpy(devname, p, devname_len);
     310            /* devname[devname_len] = '\0'; - not really needed */
     311            p = end;
     312        } else
     313        if (value_idx == 6) {
     314            // TODO: *sectorsize (don't know how to find out sectorsize)
     315            vec[0] += strtoull(p, NULL, 10);
     316        } else
     317        if (value_idx == 10) {
     318            // TODO: *sectorsize (don't know how to find out sectorsize)
    262319            vec[1] += strtoull(p, NULL, 10);
    263             while (*p != '\n' && *p != '\0') p++;
     320 skip_line:
     321            while (*p != '\n' && *p != '\0')
     322                p++;
    264323            continue;
    265324        }
    266         while (*p > ' ') p++; // skip over value
     325        while ((unsigned char)(*p) > ' ') // skip over value
     326            p++;
    267327    }
    268328    return 0;
     
    770830typedef s_stat* init_func(const char *param);
    771831
     832// Deprecated %NNNd is to be removed, -d MSEC supersedes it
    772833static const char options[] ALIGN1 = "ncmsfixptbdr";
    773834static init_func *const init_functions[] = {
     
    793854    s_stat *last = NULL;
    794855    s_stat *s;
     856    char *opt_d;
    795857    char *cur, *prev;
    796858
     
    798860
    799861    xchdir("/proc");
    800 
    801     if (!argv[1])
    802         bb_show_usage();
    803862
    804863    if (open_read_close("version", buf, sizeof(buf)-1) > 0) {
     
    807866    }
    808867
    809     // Can use argv[1] directly, but this will mess up
     868    if (getopt32(argv, "d:", &opt_d))
     869        init_delay(opt_d);
     870    argv += optind;
     871
     872    if (!argv[0])
     873        bb_show_usage();
     874
     875    // Can use argv[0] directly, but this will mess up
    810876    // parameters as seen by e.g. ps. Making a copy...
    811     cur = xstrdup(argv[1]);
     877    cur = xstrdup(argv[0]);
    812878    while (1) {
    813879        char *param, *p;
  • branches/3.2/mindi-busybox/procps/pgrep.c

    r2725 r3232  
    77 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
     9
     10//usage:#define pgrep_trivial_usage
     11//usage:       "[-flnovx] [-s SID|-P PPID|PATTERN]"
     12//usage:#define pgrep_full_usage "\n\n"
     13//usage:       "Display process(es) selected by regex PATTERN\n"
     14//usage:     "\n    -l  Show command name too"
     15//usage:     "\n    -f  Match against entire command line"
     16//usage:     "\n    -n  Show the newest process only"
     17//usage:     "\n    -o  Show the oldest process only"
     18//usage:     "\n    -v  Negate the match"
     19//usage:     "\n    -x  Match whole name (not substring)"
     20//usage:     "\n    -s  Match session ID (0 for current)"
     21//usage:     "\n    -P  Match parent process ID"
     22//usage:
     23//usage:#define pkill_trivial_usage
     24//usage:       "[-l|-SIGNAL] [-fnovx] [-s SID|-P PPID|PATTERN]"
     25//usage:#define pkill_full_usage "\n\n"
     26//usage:       "Send a signal to process(es) selected by regex PATTERN\n"
     27//usage:     "\n    -l  List all signals"
     28//usage:     "\n    -f  Match against entire command line"
     29//usage:     "\n    -n  Signal the newest process only"
     30//usage:     "\n    -o  Signal the oldest process only"
     31//usage:     "\n    -v  Negate the match"
     32//usage:     "\n    -x  Match whole name (not substring)"
     33//usage:     "\n    -s  Match session ID (0 for current)"
     34//usage:     "\n    -P  Match parent process ID"
     35
    936#include "libbb.h"
    1037#include "xregex.h"
     
    102129
    103130    if (argv[0])
    104         xregcomp(&re_buffer, argv[0], 0);
     131        xregcomp(&re_buffer, argv[0], REG_EXTENDED | REG_NOSUB);
    105132
    106133    matched_pid = 0;
  • branches/3.2/mindi-busybox/procps/pidof.c

    r2725 r3232  
    77 * Licensed under GPLv2, see file LICENSE in this source tree.
    88 */
     9
     10//usage:#if (ENABLE_FEATURE_PIDOF_SINGLE || ENABLE_FEATURE_PIDOF_OMIT)
     11//usage:#define pidof_trivial_usage
     12//usage:       "[OPTIONS] [NAME]..."
     13//usage:#define USAGE_PIDOF "\n"
     14//usage:#else
     15//usage:#define pidof_trivial_usage
     16//usage:       "[NAME]..."
     17//usage:#define USAGE_PIDOF /* none */
     18//usage:#endif
     19//usage:#define pidof_full_usage "\n\n"
     20//usage:       "List PIDs of all processes with names that match NAMEs"
     21//usage:    USAGE_PIDOF
     22//usage:    IF_FEATURE_PIDOF_SINGLE(
     23//usage:     "\n    -s  Show only one PID"
     24//usage:    )
     25//usage:    IF_FEATURE_PIDOF_OMIT(
     26//usage:     "\n    -o PID  Omit given pid"
     27//usage:     "\n        Use %PPID to omit pid of pidof's parent"
     28//usage:    )
     29//usage:
     30//usage:#define pidof_example_usage
     31//usage:       "$ pidof init\n"
     32//usage:       "1\n"
     33//usage:    IF_FEATURE_PIDOF_OMIT(
     34//usage:       "$ pidof /bin/sh\n20351 5973 5950\n")
     35//usage:    IF_FEATURE_PIDOF_OMIT(
     36//usage:       "$ pidof /bin/sh -o %PPID\n20351 5950")
    937
    1038#include "libbb.h"
  • branches/3.2/mindi-busybox/procps/pmap.c

    r2725 r3232  
    99 */
    1010
    11 //applet:IF_PMAP(APPLET(pmap, _BB_DIR_USR_BIN, _BB_SUID_DROP))
    12 //kbuild:lib-$(CONFIG_PMAP)     += pmap.o
    13 
    1411//config:config PMAP
    1512//config:       bool "pmap"
     
    1815//config:         Display processes' memory mappings.
    1916
     17//applet:IF_PMAP(APPLET(pmap, BB_DIR_USR_BIN, BB_SUID_DROP))
     18//kbuild:lib-$(CONFIG_PMAP) += pmap.o
     19
    2020//usage:#define pmap_trivial_usage
    21 //usage:       "[-x][-q] PID"
     21//usage:       "[-xq] PID"
    2222//usage:#define pmap_full_usage "\n\n"
    23 //usage:       "Display detailed precesses' memory usage\n"
    24 //usage:       "\nOptions:"
    25 //usage:       "\n     -x              show details"
    26 //usage:       "\n     -q              quiet"
     23//usage:       "Display detailed process memory usage"
     24//usage:     "\n"
     25//usage:     "\n    -x  Show details"
     26//usage:     "\n    -q  Quiet"
    2727
    2828#include "libbb.h"
  • branches/3.2/mindi-busybox/procps/powertop.c

    r2725 r3232  
    1010 */
    1111
    12 //applet:IF_POWERTOP(APPLET(powertop, _BB_DIR_BIN, _BB_SUID_DROP))
     12//applet:IF_POWERTOP(APPLET(powertop, BB_DIR_USR_SBIN, BB_SUID_DROP))
    1313
    1414//kbuild:lib-$(CONFIG_POWERTOP) += powertop.o
     
    394394    char line[15 + 3 + 128];
    395395    int n;
    396     ullong totalticks;
    397396    FILE *fp;
    398397
    399398    buf[0] = '\0';
    400     totalticks = 0;
    401399
    402400    n = 0;
     
    496494 */
    497495static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
    498                   unsigned int *edx)
     496                unsigned int *edx)
    499497{
    500498    /* EAX value specifies what information to return */
     
    653651        bb_putchar('\n');
    654652        bb_error_msg("no stats available; run as root or"
    655                 " enable the cpufreq_stats module");
     653                " enable the timer_stats module");
    656654    }
    657655}
  • branches/3.2/mindi-busybox/procps/ps.c

    r2725 r3232  
    1010 */
    1111
     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
    1264#include "libbb.h"
     65#ifdef __linux__
     66# include <sys/sysinfo.h>
     67#endif
    1368
    1469/* Absolute maximum on output line length */
    1570enum { MAX_WIDTH = 2*1024 };
    1671
     72#if ENABLE_FEATURE_PS_TIME || ENABLE_FEATURE_PS_LONG
     73static 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
    1797#if ENABLE_DESKTOP
    1898
    1999#include <sys/times.h> /* for times() */
    20100#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 */
    32124typedef struct {
    33125    uint16_t width;
     
    49141    unsigned long long seconds_since_boot;
    50142#endif
    51     char default_o[sizeof(DEFAULT_O_STR)];
    52143} FIX_ALIASING;
    53144#define G (*(struct globals*)&bb_common_bufsiz1)
     
    60151#define kernel_HZ          (G.kernel_HZ         )
    61152#define seconds_since_boot (G.seconds_since_boot)
    62 #define default_o          (G.default_o         )
    63153#define INIT_G() do { } while (0)
    64154
     
    69159    ptrdiff_t *ep = (ptrdiff_t *) environ;
    70160
    71     while (*ep++);
     161    while (*ep++)
     162        continue;
    72163    while (*ep) {
    73164        if (ep[0] == findme) {
     
    132223static unsigned get_kernel_HZ(void)
    133224{
    134     //char buf[64];
    135     struct sysinfo info;
    136225
    137226    if (kernel_HZ)
     
    143232        kernel_HZ = get_HZ_by_waiting();
    144233
    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();
    151235
    152236    return kernel_HZ;
     
    185269}
    186270
     271static void func_state(char *buf, int size, const procps_status_t *ps)
     272{
     273    safe_strncpy(buf, ps->state, size+1);
     274}
     275
    187276static void func_args(char *buf, int size, const procps_status_t *ps)
    188277{
     
    301390
    302391static const ps_out_t out_spec[] = {
    303 // Mandated by POSIX:
     392/* Mandated by http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html: */
    304393    { 8                  , "user"  ,"USER"   ,func_user  ,PSSCAN_UIDGID  },
    305394    { 8                  , "group" ,"GROUP"  ,func_group ,PSSCAN_UIDGID  },
     
    323412    { 6                  , "tty"   ,"TT"     ,func_tty   ,PSSCAN_TTY     },
    324413    { 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   },
    326416    { 4                  , "rss"   ,"RSS"    ,func_rss   ,PSSCAN_RSS     },
    327417#if ENABLE_SELINUX
     
    460550}
    461551
     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
    462559int ps_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    463560int ps_main(int argc UNUSED_PARAM, char **argv)
     
    465562    procps_status_t *p;
    466563    llist_t* opt_o = NULL;
     564    char default_o[sizeof(DEFAULT_O_STR)];
    467565    int opt;
    468566    enum {
     
    502600        } while (opt_o);
    503601    } 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 */
    505603#if ENABLE_SELINUX
    506604        if (!(opt & OPT_Z) || !is_selinux_enabled()) {
     
    552650        OPT_Z = (1 << 0) * ENABLE_SELINUX,
    553651        OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS,
     652        OPT_l = (1 << ENABLE_SELINUX) * (1 << ENABLE_FEATURE_SHOW_THREADS) * ENABLE_FEATURE_PS_LONG,
    554653    };
     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
    555660    int opts = 0;
    556     /* If we support any options, parse argv */
    557 #if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE
    558661# if ENABLE_FEATURE_PS_WIDE
    559662    /* -w is a bit complicated */
    560663    int w_count = 0;
    561664    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);
    563667    /* if w is given once, GNU ps sets the width to 132,
    564668     * if w is given more than once, it is "unlimited"
     
    575679    /* -w is not supported, only -Z and/or -T */
    576680    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"));
    578682# endif
    579 #endif
    580 
    581 #if ENABLE_SELINUX
     683
     684# if ENABLE_SELINUX
    582685    if ((opts & OPT_Z) && is_selinux_enabled()) {
    583686        psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT
     
    585688        puts("  PID CONTEXT                          STAT COMMAND");
    586689    } 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 {
    589720        puts("  PID USER       VSZ STAT COMMAND");
    590721    }
     
    592723        psscan_flags |= PSSCAN_TASKS;
    593724    }
     725#endif
    594726
    595727    p = NULL;
     
    605737#endif
    606738        {
    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
    612780            {
    613                 char buf6[6];
    614                 smart_ulltoa5(p->vsz, buf6, " mgtpezy");
    615                 buf6[5] = '\0';
     781                const char *user = get_cached_username(p->uid);
    616782                len = printf("%5u %-8.8s %s %s  ",
    617783                    p->pid, user, buf6, p->state);
  • branches/3.2/mindi-busybox/procps/renice.c

    r2725 r3232  
    1919 *   following IDs (if any).  Multiple switches are allowed.
    2020 */
     21
     22//usage:#define renice_trivial_usage
     23//usage:       "{{-n INCREMENT} | PRIORITY} [[-p | -g | -u] ID...]"
     24//usage:#define renice_full_usage "\n\n"
     25//usage:       "Change scheduling priority for a running process\n"
     26//usage:     "\n    -n  Adjust current nice value (smaller is faster)"
     27//usage:     "\n    -p  Process id(s) (default)"
     28//usage:     "\n    -g  Process group id(s)"
     29//usage:     "\n    -u  Process user name(s) and/or id(s)"
    2130
    2231#include "libbb.h"
  • branches/3.2/mindi-busybox/procps/smemcap.c

    r2725 r3232  
    99*/
    1010
    11 //applet:IF_SMEMCAP(APPLET(smemcap, _BB_DIR_USR_BIN, _BB_SUID_DROP))
     11//applet:IF_SMEMCAP(APPLET(smemcap, BB_DIR_USR_BIN, BB_SUID_DROP))
    1212
    1313//kbuild:lib-$(CONFIG_SMEMCAP) += smemcap.o
     
    2121
    2222#include "libbb.h"
    23 #include "archive.h"
     23#include "bb_archive.h"
    2424
    2525struct fileblock {
  • branches/3.2/mindi-busybox/procps/sysctl.c

    r2725 r3232  
    1212 */
    1313
     14//usage:#define sysctl_trivial_usage
     15//usage:       "[OPTIONS] [KEY[=VALUE]]..."
     16//usage:#define sysctl_full_usage "\n\n"
     17//usage:       "Show/set kernel parameters\n"
     18//usage:     "\n    -e  Don't warn about unknown keys"
     19//usage:     "\n    -n  Don't show key names"
     20//usage:     "\n    -a  Show all values"
     21/* Same as -a, no need to show it */
     22/* //usage:     "\n -A  Show all values in table form" */
     23//usage:     "\n    -w  Set values"
     24//usage:     "\n    -p FILE Set values from FILE (default /etc/sysctl.conf)"
     25//usage:     "\n    -q      Set values silently"
     26//usage:
     27//usage:#define sysctl_example_usage
     28//usage:       "sysctl [-n] [-e] variable...\n"
     29//usage:       "sysctl [-n] [-e] [-q] -w variable=value...\n"
     30//usage:       "sysctl [-n] [-e] -a\n"
     31//usage:       "sysctl [-n] [-e] [-q] -p file   (default /etc/sysctl.conf)\n"
     32//usage:       "sysctl [-n] [-e] -A\n"
     33
    1434#include "libbb.h"
    1535
     
    2040    FLAG_SHOW_ALL        = 1 << 3,
    2141    FLAG_PRELOAD_FILE    = 1 << 4,
     42/* TODO: procps 3.2.8 seems to not require -w for KEY=VAL to work: */
    2243    FLAG_WRITE           = 1 << 5,
     44    FLAG_QUIET           = 1 << 6,
    2345};
    24 #define OPTION_STR "neAapw"
     46#define OPTION_STR "neAapwq"
    2547
    2648static void sysctl_dots_to_slashes(char *name)
     
    127149        xwrite_str(fd, value);
    128150        close(fd);
    129         if (option_mask32 & FLAG_SHOW_KEYS)
    130             printf("%s = ", outname);
    131         puts(value);
     151        if (!(option_mask32 & FLAG_QUIET)) {
     152            if (option_mask32 & FLAG_SHOW_KEYS)
     153                printf("%s = ", outname);
     154            puts(value);
     155        }
    132156    } else {
    133157        char c;
     
    182206            /* if path was ".", drop "./" prefix: */
    183207            retval |= sysctl_act_recursive((next[0] == '.' && next[1] == '/') ?
    184                         next + 2 : next);
     208                    next + 2 : next);
    185209            free(next);
    186210        }
     
    207231    /* Must do it _after_ config_open(): */
    208232    xchdir("/proc/sys");
    209     /* xchroot(".") - if you are paranoid */
     233    /* xchroot("/proc/sys") - if you are paranoid */
    210234
    211235//TODO: ';' is comment char too
     
    243267    }
    244268    xchdir("/proc/sys");
    245     /* xchroot(".") - if you are paranoid */
     269    /* xchroot("/proc/sys") - if you are paranoid */
    246270    if (opt & (FLAG_TABLE_FORMAT | FLAG_SHOW_ALL)) {
    247271        return sysctl_act_recursive(".");
  • branches/3.2/mindi-busybox/procps/top.c

    r2725 r3232  
    2020 * Sept 2008: Vineet Gupta <vineet.gupta@arc.com>
    2121 * Added Support for reporting SMP Information
    22  * - CPU where Process was last seen running
     22 * - CPU where process was last seen running
    2323 *   (to see effect of sched_setaffinity() etc)
    24  * - CPU Time Split (idle/IO/wait etc) PER CPU
     24 * - CPU time split (idle/IO/wait etc) per CPU
    2525 *
    2626 * Copyright (c) 1992 Branko Lankester
     
    3131 * Licensed under GPLv2, see file LICENSE in this source tree.
    3232 */
     33/* How to snapshot /proc for debugging top problems:
     34 * for f in /proc/[0-9]*""/stat; do
     35 *         n=${f#/proc/}
     36 *         n=${n%/stat}_stat
     37 *         cp $f $n
     38 * done
     39 * cp /proc/stat /proc/meminfo /proc/loadavg .
     40 * top -bn1 >top.out
     41 *
     42 * ...and how to run top on it on another machine:
     43 * rm -rf proc; mkdir proc
     44 * for f in [0-9]*_stat; do
     45 *         p=${f%_stat}
     46 *         mkdir -p proc/$p
     47 *         cp $f proc/$p/stat
     48 * done
     49 * cp stat meminfo loadavg proc
     50 * chroot . ./top -bn1 >top1.out
     51 */
     52
     53//config:config TOP
     54//config:   bool "top"
     55//config:   default y
     56//config:   help
     57//config:     The top program provides a dynamic real-time view of a running
     58//config:     system.
     59//config:
     60//config:config FEATURE_TOP_CPU_USAGE_PERCENTAGE
     61//config:   bool "Show CPU per-process usage percentage"
     62//config:   default y
     63//config:   depends on TOP
     64//config:   help
     65//config:     Make top display CPU usage for each process.
     66//config:     This adds about 2k.
     67//config:
     68//config:config FEATURE_TOP_CPU_GLOBAL_PERCENTS
     69//config:   bool "Show CPU global usage percentage"
     70//config:   default y
     71//config:   depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE
     72//config:   help
     73//config:     Makes top display "CPU: NN% usr NN% sys..." line.
     74//config:     This adds about 0.5k.
     75//config:
     76//config:config FEATURE_TOP_SMP_CPU
     77//config:   bool "SMP CPU usage display ('c' key)"
     78//config:   default y
     79//config:   depends on FEATURE_TOP_CPU_GLOBAL_PERCENTS
     80//config:   help
     81//config:     Allow 'c' key to switch between individual/cumulative CPU stats
     82//config:     This adds about 0.5k.
     83//config:
     84//config:config FEATURE_TOP_DECIMALS
     85//config:   bool "Show 1/10th of a percent in CPU/mem statistics"
     86//config:   default y
     87//config:   depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE
     88//config:   help
     89//config:     Show 1/10th of a percent in CPU/mem statistics.
     90//config:     This adds about 0.3k.
     91//config:
     92//config:config FEATURE_TOP_SMP_PROCESS
     93//config:   bool "Show CPU process runs on ('j' field)"
     94//config:   default y
     95//config:   depends on TOP
     96//config:   help
     97//config:     Show CPU where process was last found running on.
     98//config:     This is the 'j' field.
     99//config:
     100//config:config FEATURE_TOPMEM
     101//config:   bool "Topmem command ('s' key)"
     102//config:   default y
     103//config:   depends on TOP
     104//config:   help
     105//config:     Enable 's' in top (gives lots of memory info).
    33106
    34107#include "libbb.h"
     
    74147    top_status_t *top;
    75148    int ntop;
     149    smallint inverted;
    76150#if ENABLE_FEATURE_TOPMEM
    77151    smallint sort_field;
    78     smallint inverted;
    79152#endif
    80153#if ENABLE_FEATURE_TOP_SMP_CPU
    81154    smallint smp_cpu_info; /* one/many cpu info lines? */
    82155#endif
     156    unsigned lines;  /* screen height */
    83157#if ENABLE_FEATURE_USE_TERMIOS
    84158    struct termios initial_settings;
     159    int scroll_ofs;
     160#define G_scroll_ofs G.scroll_ofs
     161#else
     162#define G_scroll_ofs 0
    85163#endif
    86164#if !ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     
    100178    int num_cpus;
    101179#endif
     180#if ENABLE_FEATURE_USE_TERMIOS
     181    char kbd_input[KEYCODE_BUFFER_SIZE];
     182#endif
    102183    char line_buf[80];
    103184}; //FIX_ALIASING; - large code growth
     
    108189    char BUG_line_buf_too_small[LINE_BUF_SIZE > 80 ? 1 : -1];
    109190};
    110 #define INIT_G() do { } while (0)
    111191#define top              (G.top               )
    112192#define ntop             (G.ntop              )
     
    125205#define total_pcpu       (G.total_pcpu        )
    126206#define line_buf         (G.line_buf          )
     207#define INIT_G() do { } while (0)
    127208
    128209enum {
     
    176257        cmp_val = (*sort_function[i])(a, b);
    177258        if (cmp_val != 0)
    178             return cmp_val;
    179     }
    180     return 0;
     259            break;
     260    }
     261    return inverted ? -cmp_val : cmp_val;
    181262}
    182263
     
    520601    /* what info of the processes is shown */
    521602    printf(OPT_BATCH_MODE ? "%.*s" : "\033[7m%.*s\033[0m", scr_width,
    522         "  PID  PPID USER     STAT   VSZ %MEM"
     603        "  PID  PPID USER     STAT   VSZ %VSZ"
    523604        IF_FEATURE_TOP_SMP_PROCESS(" CPU")
    524605        IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(" %CPU")
     
    538619#endif
    539620    /*
    540      * MEM% = s->vsz/MemTotal
     621     * %VSZ = s->vsz/MemTotal
    541622     */
    542623    pmem_shift = BITS_PER_INT-11;
     
    547628        pmem_shift -= 2;
    548629    }
    549     pmem_half = (1U << pmem_shift) / (ENABLE_FEATURE_TOP_DECIMALS? 20 : 2);
     630    pmem_half = (1U << pmem_shift) / (ENABLE_FEATURE_TOP_DECIMALS ? 20 : 2);
    550631#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    551632    busy_jifs = cur_jif.busy - prev_jif.busy;
     
    578659        pcpu_shift -= 2;
    579660    }
    580     pcpu_half = (1U << pcpu_shift) / (ENABLE_FEATURE_TOP_DECIMALS? 20 : 2);
     661    pcpu_half = (1U << pcpu_shift) / (ENABLE_FEATURE_TOP_DECIMALS ? 20 : 2);
    581662    /* printf(" pmem_scale=%u pcpu_scale=%u ", pmem_scale, pcpu_scale); */
    582663#endif
     
    584665    /* Ok, all preliminary data is ready, go through the list */
    585666    scr_width += 2; /* account for leading '\n' and trailing NUL */
    586     if (lines_rem > ntop)
    587         lines_rem = ntop;
    588     s = top;
     667    if (lines_rem > ntop - G_scroll_ofs)
     668        lines_rem = ntop - G_scroll_ofs;
     669    s = top + G_scroll_ofs;
    589670    while (--lines_rem >= 0) {
    590671        unsigned col;
     
    598679        else
    599680            sprintf(vsz_str_buf, "%7ld", s->vsz);
    600         /* PID PPID USER STAT VSZ %MEM [%CPU] COMMAND */
     681        /* PID PPID USER STAT VSZ %VSZ [%CPU] COMMAND */
    601682        col = snprintf(line_buf, scr_width,
    602683                "\n" "%5u%6u %-8.8s %s%s" FMT
     
    631712    free(top);
    632713    top = NULL;
    633     ntop = 0;
    634714}
    635715
     
    638718static void reset_term(void)
    639719{
    640     tcsetattr_stdin_TCSANOW(&initial_settings);
     720    if (!OPT_BATCH_MODE)
     721        tcsetattr_stdin_TCSANOW(&initial_settings);
    641722    if (ENABLE_FEATURE_CLEAN_UP) {
    642723        clearmems();
     
    647728}
    648729
    649 static void sig_catcher(int sig UNUSED_PARAM)
     730static void sig_catcher(int sig)
    650731{
    651732    reset_term();
    652     _exit(EXIT_FAILURE);
     733    kill_myself_with_sig(sig);
    653734}
    654735
     
    775856#define HDR_STR "  PID   VSZ VSZRW   RSS (SHR) DIRTY (SHR) STACK"
    776857#define MIN_WIDTH sizeof(HDR_STR)
    777     const topmem_status_t *s = topmem;
     858    const topmem_status_t *s = topmem + G_scroll_ofs;
    778859
    779860    display_topmem_header(scr_width, &lines_rem);
    780861    strcpy(line_buf, HDR_STR " COMMAND");
    781     line_buf[5 + sort_field * 6] = '*';
     862    line_buf[11 + sort_field * 6] = "^_"[inverted];
    782863    printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width, line_buf);
    783864    lines_rem--;
    784865
    785     if (lines_rem > ntop)
    786         lines_rem = ntop;
     866    if (lines_rem > ntop - G_scroll_ofs)
     867        lines_rem = ntop - G_scroll_ofs;
    787868    while (--lines_rem >= 0) {
    788869        /* PID VSZ VSZRW RSS (SHR) DIRTY (SHR) COMMAND */
     
    832913        | PSSCAN_SMAPS
    833914        | PSSCAN_COMM,
     915    EXIT_MASK = (unsigned)-1,
    834916};
     917
     918#if ENABLE_FEATURE_USE_TERMIOS
     919static unsigned handle_input(unsigned scan_mask, unsigned interval)
     920{
     921    struct pollfd pfd[1];
     922
     923    if (option_mask32 & OPT_EOF) {
     924        /* EOF on stdin ("top </dev/null") */
     925        sleep(interval);
     926        return scan_mask;
     927    }
     928
     929    pfd[0].fd = 0;
     930    pfd[0].events = POLLIN;
     931
     932    while (1) {
     933        int32_t c;
     934
     935        c = read_key(STDIN_FILENO, G.kbd_input, interval * 1000);
     936        if (c == -1 && errno != EAGAIN) {
     937            /* error/EOF */
     938            option_mask32 |= OPT_EOF;
     939            break;
     940        }
     941        interval = 0;
     942
     943        if (c == initial_settings.c_cc[VINTR])
     944            return EXIT_MASK;
     945        if (c == initial_settings.c_cc[VEOF])
     946            return EXIT_MASK;
     947
     948        if (c == KEYCODE_UP) {
     949            G_scroll_ofs--;
     950            goto normalize_ofs;
     951        }
     952        if (c == KEYCODE_DOWN) {
     953            G_scroll_ofs++;
     954            goto normalize_ofs;
     955        }
     956        if (c == KEYCODE_HOME) {
     957            G_scroll_ofs = 0;
     958            break;
     959        }
     960        if (c == KEYCODE_END) {
     961            G_scroll_ofs = ntop - G.lines / 2;
     962            goto normalize_ofs;
     963        }
     964        if (c == KEYCODE_PAGEUP) {
     965            G_scroll_ofs -= G.lines / 2;
     966            goto normalize_ofs;
     967        }
     968        if (c == KEYCODE_PAGEDOWN) {
     969            G_scroll_ofs += G.lines / 2;
     970 normalize_ofs:
     971            if (G_scroll_ofs >= ntop)
     972                G_scroll_ofs = ntop - 1;
     973            if (G_scroll_ofs < 0)
     974                G_scroll_ofs = 0;
     975            break;
     976        }
     977
     978        c |= 0x20; /* lowercase */
     979        if (c == 'q')
     980            return EXIT_MASK;
     981
     982        if (c == 'n') {
     983            IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;)
     984            sort_function[0] = pid_sort;
     985            continue;
     986        }
     987        if (c == 'm') {
     988            IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;)
     989            sort_function[0] = mem_sort;
     990# if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     991            sort_function[1] = pcpu_sort;
     992            sort_function[2] = time_sort;
     993# endif
     994            continue;
     995        }
     996# if ENABLE_FEATURE_SHOW_THREADS
     997        if (c == 'h'
     998        IF_FEATURE_TOPMEM(&& scan_mask != TOPMEM_MASK)
     999        ) {
     1000            scan_mask ^= PSSCAN_TASKS;
     1001            continue;
     1002        }
     1003# endif
     1004# if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     1005        if (c == 'p') {
     1006            IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;)
     1007            sort_function[0] = pcpu_sort;
     1008            sort_function[1] = mem_sort;
     1009            sort_function[2] = time_sort;
     1010            continue;
     1011        }
     1012        if (c == 't') {
     1013            IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;)
     1014            sort_function[0] = time_sort;
     1015            sort_function[1] = mem_sort;
     1016            sort_function[2] = pcpu_sort;
     1017            continue;
     1018        }
     1019#  if ENABLE_FEATURE_TOPMEM
     1020        if (c == 's') {
     1021            scan_mask = TOPMEM_MASK;
     1022            free(prev_hist);
     1023            prev_hist = NULL;
     1024            prev_hist_count = 0;
     1025            sort_field = (sort_field + 1) % NUM_SORT_FIELD;
     1026            continue;
     1027        }
     1028#  endif
     1029        if (c == 'r') {
     1030            inverted ^= 1;
     1031            continue;
     1032        }
     1033#  if ENABLE_FEATURE_TOP_SMP_CPU
     1034        /* procps-2.0.18 uses 'C', 3.2.7 uses '1' */
     1035        if (c == 'c' || c == '1') {
     1036            /* User wants to toggle per cpu <> aggregate */
     1037            if (smp_cpu_info) {
     1038                free(cpu_prev_jif);
     1039                free(cpu_jif);
     1040                cpu_jif = &cur_jif;
     1041                cpu_prev_jif = &prev_jif;
     1042            } else {
     1043                /* Prepare for xrealloc() */
     1044                cpu_jif = cpu_prev_jif = NULL;
     1045            }
     1046            num_cpus = 0;
     1047            smp_cpu_info = !smp_cpu_info;
     1048            get_jiffy_counts();
     1049            continue;
     1050        }
     1051#  endif
     1052# endif
     1053        break; /* unknown key -> force refresh */
     1054    }
     1055
     1056    return scan_mask;
     1057}
     1058#endif
     1059
     1060//usage:#if ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_TOP_SMP_CPU
     1061//usage:# define IF_SHOW_THREADS_OR_TOP_SMP(...) __VA_ARGS__
     1062//usage:#else
     1063//usage:# define IF_SHOW_THREADS_OR_TOP_SMP(...)
     1064//usage:#endif
     1065//usage:#define top_trivial_usage
     1066//usage:       "[-b] [-nCOUNT] [-dSECONDS]" IF_FEATURE_TOPMEM(" [-m]")
     1067//usage:#define top_full_usage "\n\n"
     1068//usage:       "Provide a view of process activity in real time."
     1069//usage:   "\n""Read the status of all processes from /proc each SECONDS"
     1070//usage:   "\n""and display a screenful of them."
     1071//usage:   "\n""Keys:"
     1072//usage:   "\n""    N/M"
     1073//usage:                IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/P")
     1074//usage:                IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/T")
     1075//usage:           ": " IF_FEATURE_TOPMEM("show CPU usage, ") "sort by pid/mem"
     1076//usage:                IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/cpu")
     1077//usage:                IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/time")
     1078//usage:    IF_FEATURE_TOPMEM(
     1079//usage:   "\n""    S: show memory"
     1080//usage:    )
     1081//usage:   "\n""    R: reverse sort"
     1082//usage:    IF_SHOW_THREADS_OR_TOP_SMP(
     1083//usage:   "\n""    "
     1084//usage:                IF_FEATURE_SHOW_THREADS("H: toggle threads")
     1085//usage:                IF_FEATURE_SHOW_THREADS(IF_FEATURE_TOP_SMP_CPU(", "))
     1086//usage:                IF_FEATURE_TOP_SMP_CPU("1: toggle SMP")
     1087//usage:    )
     1088//usage:   "\n""    Q,^C: exit"
     1089//usage:   "\n"
     1090//usage:   "\n""Options:"
     1091//usage:   "\n""    -b  Batch mode"
     1092//usage:   "\n""    -n N    Exit after N iterations"
     1093//usage:   "\n""    -d N    Delay between updates"
     1094//usage:    IF_FEATURE_TOPMEM(
     1095//usage:   "\n""    -m  Same as 's' key"
     1096//usage:    )
     1097
     1098/* Interactive testing:
     1099 * echo sss | ./busybox top
     1100 * - shows memory screen
     1101 * echo sss | ./busybox top -bn1 >mem
     1102 * - saves memory screen - the *whole* list, not first NROWS processes!
     1103 * echo .m.s.s.s.s.s.s.q | ./busybox top -b >z
     1104 * - saves several different screens, and exits
     1105 *
     1106 * TODO: -i STRING param as a better alternative?
     1107 */
    8351108
    8361109int top_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     
    8381111{
    8391112    int iterations;
    840     unsigned lines, col;
    841     int lines_rem;
     1113    unsigned col;
    8421114    unsigned interval;
    8431115    char *str_interval, *str_iterations;
     
    8451117#if ENABLE_FEATURE_USE_TERMIOS
    8461118    struct termios new_settings;
    847     struct pollfd pfd[1];
    848     unsigned char c;
    849 
    850     pfd[0].fd = 0;
    851     pfd[0].events = POLLIN;
    8521119#endif
    8531120
     
    8861153    /* change to /proc */
    8871154    xchdir("/proc");
    888 #if ENABLE_FEATURE_USE_TERMIOS
    889     tcgetattr(0, (void *) &initial_settings);
    890     memcpy(&new_settings, &initial_settings, sizeof(new_settings));
    891     /* unbuffered input, turn off echo */
    892     new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL);
    893 
    894     bb_signals(BB_FATAL_SIGS, sig_catcher);
    895     tcsetattr_stdin_TCSANOW(&new_settings);
    896 #endif
    8971155
    8981156#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     
    9041162#endif
    9051163
    906     while (1) {
     1164    if (OPT_BATCH_MODE) {
     1165        option_mask32 |= OPT_EOF;
     1166    }
     1167#if ENABLE_FEATURE_USE_TERMIOS
     1168    else {
     1169        tcgetattr(0, (void *) &initial_settings);
     1170        memcpy(&new_settings, &initial_settings, sizeof(new_settings));
     1171        /* unbuffered input, turn off echo */
     1172        new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL);
     1173        tcsetattr_stdin_TCSANOW(&new_settings);
     1174    }
     1175
     1176    bb_signals(BB_FATAL_SIGS, sig_catcher);
     1177
     1178    /* Eat initial input, if any */
     1179    scan_mask = handle_input(scan_mask, 0);
     1180#endif
     1181
     1182    while (scan_mask != EXIT_MASK) {
    9071183        procps_status_t *p = NULL;
    9081184
    909         lines = 24; /* default */
    910         col = 79;
     1185        if (OPT_BATCH_MODE) {
     1186            G.lines = INT_MAX;
     1187            col = LINE_BUF_SIZE - 2; /* +2 bytes for '\n', NUL */
     1188        } else {
     1189            G.lines = 24; /* default */
     1190            col = 79;
    9111191#if ENABLE_FEATURE_USE_TERMIOS
    912         /* We output to stdout, we need size of stdout (not stdin)! */
    913         get_terminal_width_height(STDOUT_FILENO, &col, &lines);
    914         if (lines < 5 || col < 10) {
    915             sleep(interval);
    916             continue;
    917         }
    918 #endif
    919         if (col > LINE_BUF_SIZE-2) /* +2 bytes for '\n', NUL, */
    920             col = LINE_BUF_SIZE-2;
     1192            /* We output to stdout, we need size of stdout (not stdin)! */
     1193            get_terminal_width_height(STDOUT_FILENO, &col, &G.lines);
     1194            if (G.lines < 5 || col < 10) {
     1195                sleep(interval);
     1196                continue;
     1197            }
     1198#endif
     1199            if (col > LINE_BUF_SIZE - 2)
     1200                col = LINE_BUF_SIZE - 2;
     1201        }
    9211202
    9221203        /* read process IDs & status for all the processes */
     1204        ntop = 0;
    9231205        while ((p = procps_scan(p, scan_mask)) != NULL) {
    9241206            int n;
     
    9861268        }
    9871269#endif
    988         lines_rem = lines;
    989         if (OPT_BATCH_MODE) {
    990             lines_rem = INT_MAX;
    991         }
    9921270        if (scan_mask != TOPMEM_MASK)
    993             display_process_list(lines_rem, col);
     1271            display_process_list(G.lines, col);
    9941272#if ENABLE_FEATURE_TOPMEM
    9951273        else
    996             display_topmem_process_list(lines_rem, col);
     1274            display_topmem_process_list(G.lines, col);
    9971275#endif
    9981276        clearmems();
     
    10021280        sleep(interval);
    10031281#else
    1004         if (option_mask32 & (OPT_b|OPT_EOF))
    1005              /* batch mode, or EOF on stdin ("top </dev/null") */
    1006             sleep(interval);
    1007         else if (safe_poll(pfd, 1, interval * 1000) > 0) {
    1008             if (safe_read(STDIN_FILENO, &c, 1) != 1) { /* error/EOF? */
    1009                 option_mask32 |= OPT_EOF;
    1010                 continue;
    1011             }
    1012             if (c == initial_settings.c_cc[VINTR])
    1013                 break;
    1014             c |= 0x20; /* lowercase */
    1015             if (c == 'q')
    1016                 break;
    1017             if (c == 'n') {
    1018                 IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;)
    1019                 sort_function[0] = pid_sort;
    1020             }
    1021             if (c == 'm') {
    1022                 IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;)
    1023                 sort_function[0] = mem_sort;
    1024 # if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    1025                 sort_function[1] = pcpu_sort;
    1026                 sort_function[2] = time_sort;
    1027 # endif
    1028             }
    1029 # if ENABLE_FEATURE_SHOW_THREADS
    1030             if (c == 'h'
    1031              IF_FEATURE_TOPMEM(&& scan_mask != TOPMEM_MASK)
    1032             ) {
    1033                 scan_mask ^= PSSCAN_TASKS;
    1034             }
    1035 # endif
    1036 # if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    1037             if (c == 'p') {
    1038                 IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;)
    1039                 sort_function[0] = pcpu_sort;
    1040                 sort_function[1] = mem_sort;
    1041                 sort_function[2] = time_sort;
    1042             }
    1043             if (c == 't') {
    1044                 IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;)
    1045                 sort_function[0] = time_sort;
    1046                 sort_function[1] = mem_sort;
    1047                 sort_function[2] = pcpu_sort;
    1048             }
    1049 #  if ENABLE_FEATURE_TOPMEM
    1050             if (c == 's') {
    1051                 scan_mask = TOPMEM_MASK;
    1052                 free(prev_hist);
    1053                 prev_hist = NULL;
    1054                 prev_hist_count = 0;
    1055                 sort_field = (sort_field + 1) % NUM_SORT_FIELD;
    1056             }
    1057             if (c == 'r')
    1058                 inverted ^= 1;
    1059 #  endif
    1060 #  if ENABLE_FEATURE_TOP_SMP_CPU
    1061             /* procps-2.0.18 uses 'C', 3.2.7 uses '1' */
    1062             if (c == 'c' || c == '1') {
    1063                 /* User wants to toggle per cpu <> aggregate */
    1064                 if (smp_cpu_info) {
    1065                     free(cpu_prev_jif);
    1066                     free(cpu_jif);
    1067                     cpu_jif = &cur_jif;
    1068                     cpu_prev_jif = &prev_jif;
    1069                 } else {
    1070                     /* Prepare for xrealloc() */
    1071                     cpu_jif = cpu_prev_jif = NULL;
    1072                 }
    1073                 num_cpus = 0;
    1074                 smp_cpu_info = !smp_cpu_info;
    1075                 get_jiffy_counts();
    1076             }
    1077 #  endif
    1078 # endif
    1079         }
     1282        scan_mask = handle_input(scan_mask, interval);
    10801283#endif /* FEATURE_USE_TERMIOS */
    1081     } /* end of "while (1)" */
     1284    } /* end of "while (not Q)" */
    10821285
    10831286    bb_putchar('\n');
  • branches/3.2/mindi-busybox/procps/uptime.c

    r2725 r3232  
    88 */
    99
    10 /* This version of uptime doesn't display the number of users on the system,
    11  * since busybox init doesn't mess with utmp.  For folks using utmp that are
    12  * just dying to have # of users reported, feel free to write it as some type
    13  * of CONFIG_FEATURE_UTMP_SUPPORT #define
     10/* 2011     Pere Orga <gotrunks@gmail.com>
     11 *
     12 * Added FEATURE_UPTIME_UTMP_SUPPORT flag.
    1413 */
    1514
    1615/* getopt not needed */
    1716
     17//config:config UPTIME
     18//config:   bool "uptime"
     19//config:   default y
     20//config:   select PLATFORM_LINUX #sysinfo()
     21//config:   help
     22//config:     uptime gives a one line display of the current time, how long
     23//config:     the system has been running, how many users are currently logged
     24//config:     on, and the system load averages for the past 1, 5, and 15 minutes.
     25//config:
     26//config:config FEATURE_UPTIME_UTMP_SUPPORT
     27//config:   bool "Support for showing the number of users"
     28//config:   default y
     29//config:   depends on UPTIME && FEATURE_UTMP
     30//config:   help
     31//config:     Makes uptime display the number of users currently logged on.
     32
     33//usage:#define uptime_trivial_usage
     34//usage:       ""
     35//usage:#define uptime_full_usage "\n\n"
     36//usage:       "Display the time since the last boot"
     37//usage:
     38//usage:#define uptime_example_usage
     39//usage:       "$ uptime\n"
     40//usage:       "  1:55pm  up  2:30, load average: 0.09, 0.04, 0.00\n"
     41
    1842#include "libbb.h"
     43#ifdef __linux__
     44# include <sys/sysinfo.h>
     45#endif
     46
    1947
    2048#ifndef FSHIFT
    2149# define FSHIFT 16              /* nr of bits of precision */
    2250#endif
    23 #define FIXED_1         (1<<FSHIFT)     /* 1.0 as fixed-point */
    24 #define LOAD_INT(x) ((x) >> FSHIFT)
    25 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
     51#define FIXED_1      (1 << FSHIFT)     /* 1.0 as fixed-point */
     52#define LOAD_INT(x)  (unsigned)((x) >> FSHIFT)
     53#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 - 1)) * 100)
    2654
    2755
     
    2957int uptime_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
    3058{
    31     int updays, uphours, upminutes;
     59    unsigned updays, uphours, upminutes;
    3260    struct sysinfo info;
    3361    struct tm *current_time;
     
    3967    sysinfo(&info);
    4068
    41     printf(" %02d:%02d:%02d up ",
     69    printf(" %02u:%02u:%02u up ",
    4270            current_time->tm_hour, current_time->tm_min, current_time->tm_sec);
    43     updays = (int) info.uptime / (60*60*24);
     71    updays = (unsigned) info.uptime / (unsigned)(60*60*24);
    4472    if (updays)
    45         printf("%d day%s, ", updays, (updays != 1) ? "s" : "");
    46     upminutes = (int) info.uptime / 60;
    47     uphours = (upminutes / 60) % 24;
     73        printf("%u day%s, ", updays, (updays != 1) ? "s" : "");
     74    upminutes = (unsigned) info.uptime / (unsigned)60;
     75    uphours = (upminutes / (unsigned)60) % (unsigned)24;
    4876    upminutes %= 60;
    4977    if (uphours)
    50         printf("%2d:%02d, ", uphours, upminutes);
     78        printf("%2u:%02u", uphours, upminutes);
    5179    else
    52         printf("%d min, ", upminutes);
     80        printf("%u min", upminutes);
    5381
    54     printf("load average: %ld.%02ld, %ld.%02ld, %ld.%02ld\n",
     82#if ENABLE_FEATURE_UPTIME_UTMP_SUPPORT
     83    {
     84        struct utmp *ut;
     85        unsigned users = 0;
     86        while ((ut = getutent()) != NULL) {
     87            if ((ut->ut_type == USER_PROCESS) && (ut->ut_name[0] != '\0'))
     88                users++;
     89        }
     90        printf(",  %u users", users);
     91    }
     92#endif
     93
     94    printf(",  load average: %u.%02u, %u.%02u, %u.%02u\n",
    5595            LOAD_INT(info.loads[0]), LOAD_FRAC(info.loads[0]),
    5696            LOAD_INT(info.loads[1]), LOAD_FRAC(info.loads[1]),
  • branches/3.2/mindi-busybox/procps/watch.c

    r2725 r3232  
    1111/* BB_AUDIT SUSv3 N/A */
    1212/* BB_AUDIT GNU defects -- only option -n is supported. */
     13
     14//usage:#define watch_trivial_usage
     15//usage:       "[-n SEC] [-t] PROG ARGS"
     16//usage:#define watch_full_usage "\n\n"
     17//usage:       "Run PROG periodically\n"
     18//usage:     "\n    -n  Loop period in seconds (default 2)"
     19//usage:     "\n    -t  Don't print header"
     20//usage:
     21//usage:#define watch_example_usage
     22//usage:       "$ watch date\n"
     23//usage:       "Mon Dec 17 10:31:40 GMT 2000\n"
     24//usage:       "Mon Dec 17 10:31:42 GMT 2000\n"
     25//usage:       "Mon Dec 17 10:31:44 GMT 2000"
    1326
    1427#include "libbb.h"
Note: See TracChangeset for help on using the changeset viewer.