Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/procps


Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (16 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

Location:
branches/2.2.5/mindi-busybox/procps
Files:
4 added
2 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/procps/Config.in

    r821 r1765  
    66menu "Process Utilities"
    77
    8 config CONFIG_FREE
     8config FREE
    99    bool "free"
    1010    default n
     
    1414      The shared memory column should be ignored; it is obsolete.
    1515
    16 config CONFIG_FUSER
     16config FUSER
    1717    bool "fuser"
    1818    default n
     
    2222      (TCP or UDP) port open.
    2323
    24 config CONFIG_KILL
     24config KILL
    2525    bool "kill"
    2626    default n
     
    3030      signal is sent.
    3131
    32 config CONFIG_KILLALL
     32config KILLALL
    3333    bool "killall"
    3434    default n
    35     depends on CONFIG_KILL
     35    depends on KILL
    3636    help
    3737      killall sends a signal to all processes running any of the
     
    3939      sent.
    4040
    41 config CONFIG_PIDOF
     41config KILLALL5
     42    bool "killall5"
     43    default n
     44    depends on KILL
     45
     46config NMETER
     47    bool "nmeter"
     48    default n
     49    help
     50      Prints selected system stats continuously, one line per update.
     51
     52config PIDOF
    4253    bool "pidof"
    4354    default n
     
    4657      those id's on the standard output.
    4758
    48 config CONFIG_FEATURE_PIDOF_SINGLE
     59config FEATURE_PIDOF_SINGLE
    4960    bool "Enable argument for single shot (-s)"
    5061    default n
    51     depends on CONFIG_PIDOF
     62    depends on PIDOF
    5263    help
    5364      Support argument '-s' for returning only the first pid found.
    5465
    55 config CONFIG_FEATURE_PIDOF_OMIT
     66config FEATURE_PIDOF_OMIT
    5667    bool "Enable argument for omitting pids (-o)"
    5768    default n
    58     depends on CONFIG_PIDOF
     69    depends on PIDOF
    5970    help
    6071      Support argument '-o' for omitting the given pids in output.
     
    6273      of the pidof, in other words the calling shell or shell script.
    6374
    64 config CONFIG_PS
     75config PS
    6576    bool "ps"
    6677    default n
     
    6879      ps gives a snapshot of the current processes.
    6980
    70 config CONFIG_FEATURE_PS_WIDE
     81config FEATURE_PS_WIDE
    7182    bool "Enable argument for wide output (-w)"
    7283    default n
    73     depends on CONFIG_PS
     84    depends on PS
    7485    help
    7586      Support argument 'w' for wide output.
     
    7788      one, the length is unlimited.
    7889
    79 config CONFIG_RENICE
     90config RENICE
    8091    bool "renice"
    8192    default n
     
    8495      processes.
    8596
    86 config CONFIG_BB_SYSCTL
     97config BB_SYSCTL
    8798    bool "sysctl"
    8899    default n
     
    90101      Configure kernel parameters at runtime.
    91102
    92 config CONFIG_TOP
     103config TOP
    93104    bool "top"
    94105    default n
     
    97108      system.
    98109
    99 config CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    100     bool "Support showing CPU usage percentage (add 2k bytes)"
     110config FEATURE_TOP_CPU_USAGE_PERCENTAGE
     111    bool "Show CPU per-process usage percentage (adds 2k bytes)"
    101112    default y
    102     depends on CONFIG_TOP
     113    depends on TOP
    103114    help
    104       Make top display CPU usage.
     115      Make top display CPU usage for each process.
    105116
    106 config CONFIG_UPTIME
     117config FEATURE_TOP_CPU_GLOBAL_PERCENTS
     118    bool "Show CPU global usage percentage (adds 0.5k bytes)"
     119    default y
     120    depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE
     121    help
     122      Makes top display "CPU: NN% usr NN% sys..." line.
     123
     124config FEATURE_TOP_DECIMALS
     125    bool "Show 1/10th of a percent in CPU/mem statistics (adds 0.3k bytes)"
     126    default n
     127    depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE
     128    help
     129      Show 1/10th of a percent in CPU/mem statistics.
     130
     131config UPTIME
    107132    bool "uptime"
    108133    default n
     
    112137      on, and the system load averages for the past 1, 5, and 15 minutes.
    113138
     139config WATCH
     140    bool "watch"
     141    default n
     142    #huh?? select DATE
     143    help
     144      watch is used to execute a program periodically, showing
     145      output to the screen.
     146
    114147
    115148endmenu
  • branches/2.2.5/mindi-busybox/procps/free.c

    r821 r1765  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    7  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
     7 * Licensed under the GPL version 2, see the file LICENSE in this tarball.
    88 */
    99
    1010/* getopt not needed */
    1111
    12 #include "busybox.h"
    13 #include <stdio.h>
    14 #include <errno.h>
    15 #include <stdlib.h>
     12#include "libbb.h"
    1613
     14int free_main(int argc, char **argv);
    1715int free_main(int argc, char **argv)
    1816{
     
    2119
    2220    /* Kernels prior to 2.4.x will return info.mem_unit==0, so cope... */
    23     if (info.mem_unit==0) {
     21    if (info.mem_unit == 0) {
    2422        info.mem_unit=1;
    2523    }
    26     if ( info.mem_unit == 1 ) {
     24    if (info.mem_unit == 1) {
    2725        info.mem_unit=1024;
    2826
     
    4947    }
    5048
    51     if (argc > 1 && **(argv + 1) == '-')
     49    if (argc > 1 && *argv[1] == '-')
    5250        bb_show_usage();
    5351
     
    6967    return EXIT_SUCCESS;
    7068}
    71 
  • branches/2.2.5/mindi-busybox/procps/fuser.c

    r821 r1765  
    99 */
    1010
    11 #include "busybox.h"
    12 #include <stdio.h>
    13 #include <stdlib.h>
    14 #include <unistd.h>
    15 #include <string.h>
    16 #include <limits.h>
    17 #include <dirent.h>
    18 #include <signal.h>
    19 #include <sys/types.h>
    20 #include <sys/ioctl.h>
    21 #include <sys/stat.h>
    22 #include <sys/socket.h>
    23 #include <sys/sysmacros.h>
     11#include "libbb.h"
    2412
    2513#define FUSER_PROC_DIR "/proc"
     
    4735    int opt = 0;
    4836
    49     if(!(strlen(option))) return 0;
    50     if(option[0] != '-') return 0;
     37    if (!option[0])
     38        return 0;
     39    if (option[0] != '-')
     40        return 0;
    5141    ++option;
    52     while(*option != '\0') {
    53         if(*option == 'm') opt |= FUSER_OPT_MOUNT;
    54         else if(*option == 'k') opt |= FUSER_OPT_KILL;
    55         else if(*option == 's') opt |= FUSER_OPT_SILENT;
    56         else if(*option == '6') opt |= FUSER_OPT_IP6;
    57         else if(*option == '4') opt |= FUSER_OPT_IP4;
    58         else {
    59             bb_error_msg_and_die(
    60                 "Unsupported option '%c'", *option);
    61         }
     42    while (*option != '\0') {
     43        if (*option == 'm') opt |= FUSER_OPT_MOUNT;
     44        else if (*option == 'k') opt |= FUSER_OPT_KILL;
     45        else if (*option == 's') opt |= FUSER_OPT_SILENT;
     46        else if (*option == '6') opt |= FUSER_OPT_IP6;
     47        else if (*option == '4') opt |= FUSER_OPT_IP4;
     48        else
     49            bb_error_msg_and_die("unsupported option '%c'", *option);
    6250        ++option;
    6351    }
     
    6957{
    7058    struct stat f_stat;
    71     if((stat(filename, &f_stat)) < 0) return 0;
     59    if ((stat(filename, &f_stat)) < 0)
     60        return 0;
    7261    *inode = f_stat.st_ino;
    7362    *dev = f_stat.st_dev;
     
    8170
    8271    if (fd >= 0 && (fstat(fd, &buf)) == 0) {
    83         *dev =  buf.st_dev;
     72        *dev = buf.st_dev;
    8473        close(fd);
    8574        return 1;
     
    9382    char path[sizeof(FUSER_PROC_DIR)+12], tproto[5];
    9483
    95     if((sscanf(filename, "%d/%4s", port, tproto)) != 2) return 0;
    96     sprintf(path, "%s/net/%s", FUSER_PROC_DIR, tproto);
    97     if((access(path, R_OK)) != 0) return 0;
    98     *proto = bb_xstrdup(tproto);
     84    if ((sscanf(filename, "%d/%4s", port, tproto)) != 2)
     85        return 0;
     86    sprintf(path, FUSER_PROC_DIR "/net/%s", tproto);
     87    if ((access(path, R_OK)) != 0)
     88        return 0;
     89    *proto = xstrdup(tproto);
    9990    return 1;
    10091}
     
    10495    pid_list *curr = NULL, *last = NULL;
    10596
    106     if(plist->pid == 0) plist->pid = pid;
     97    if (plist->pid == 0)
     98        plist->pid = pid;
    10799    curr = plist;
    108     while(curr != NULL) {
    109         if(curr->pid == pid) return 1;
     100    while (curr != NULL) {
     101        if (curr->pid == pid)
     102            return 1;
    110103        last = curr;
    111104        curr = curr->next;
    112105    }
    113     curr = xmalloc(sizeof(pid_list));
     106    curr = xzalloc(sizeof(pid_list));
    114107    last->next = curr;
    115108    curr->pid = pid;
    116     curr->next = NULL;
     109    /*curr->next = NULL;*/
    117110    return 1;
    118111}
     
    122115    inode_list *curr = NULL, *last = NULL;
    123116
    124     if(!ilist->inode && !ilist->dev) {
     117    if (!ilist->inode && !ilist->dev) {
    125118        ilist->dev = dev;
    126119        ilist->inode = inode;
    127120    }
    128121    curr = ilist;
    129     while(curr != NULL) {
    130         if(curr->inode == inode && curr->dev == dev) return 1;
     122    while (curr != NULL) {
     123        if (curr->inode == inode && curr->dev == dev)
     124            return 1;
    131125        last = curr;
    132126        curr = curr->next;
    133127    }
    134     curr = xmalloc(sizeof(inode_list));
     128    curr = xzalloc(sizeof(inode_list));
    135129    last->next = curr;
    136130    curr->dev = dev;
    137131    curr->inode = inode;
    138     curr->next = NULL;
     132    /*curr->next = NULL;*/
    139133    return 1;
    140134}
     
    147141    ino_t tmp_inode;
    148142    dev_t tmp_dev;
    149     long long  uint64_inode;
     143    long long uint64_inode;
    150144    int tmp_port;
    151145    FILE *f;
    152146
    153     if(!fuser_find_socket_dev(&tmp_dev)) tmp_dev = 0;
    154     sprintf(path, "%s/net/%s", FUSER_PROC_DIR, proto);
    155 
    156     if (!(f = fopen(path, "r"))) return 0;
    157     while(fgets(line, FUSER_MAX_LINE, f)) {
    158         if(sscanf(line,
    159             "%*d: %64[0-9A-Fa-f]:%x %*x:%*x %*x %*x:%*x "
    160             "%*x:%*x %*x %*d %*d %llu",
    161             addr, &tmp_port, &uint64_inode) == 3) {
    162             if((strlen(addr) == 8) &&
    163                 (opts & FUSER_OPT_IP6)) continue;
    164             else if((strlen(addr) > 8) &&
    165                 (opts & FUSER_OPT_IP4)) continue;
    166             if(tmp_port == port) {
     147    if (!fuser_find_socket_dev(&tmp_dev))
     148        tmp_dev = 0;
     149    sprintf(path, FUSER_PROC_DIR "/net/%s", proto);
     150
     151    f = fopen(path, "r");
     152    if (!f)
     153        return 0;
     154    while (fgets(line, FUSER_MAX_LINE, f)) {
     155        if (sscanf(line, "%*d: %64[0-9A-Fa-f]:%x %*x:%*x %*x %*x:%*x "
     156                "%*x:%*x %*x %*d %*d %llu",
     157                addr, &tmp_port, &uint64_inode) == 3
     158        ) {
     159            if (strlen(addr) == 8 && (opts & FUSER_OPT_IP6))
     160                continue;
     161            if (strlen(addr) > 8 && (opts & FUSER_OPT_IP4))
     162                continue;
     163            if (tmp_port == port) {
    167164                tmp_inode = uint64_inode;
    168165                fuser_add_inode(ilist, tmp_dev, tmp_inode);
    169166            }
    170167        }
    171 
    172168    }
    173169    fclose(f);
     
    181177    curr = ilist;
    182178
    183     while(curr) {
    184         if((opts & FUSER_OPT_MOUNT) && curr->dev == dev)
     179    while (curr) {
     180        if ((opts & FUSER_OPT_MOUNT) && curr->dev == dev)
    185181            return 1;
    186         if(curr->inode == inode && curr->dev == dev)
     182        if (curr->inode == inode && curr->dev == dev)
    187183            return 1;
    188184        curr = curr->next;
     
    201197    dev_t dev;
    202198
    203     if (!(file = fopen(fname, "r"))) return 0;
     199    file = fopen(fname, "r");
     200    if (!file)
     201        return 0;
    204202    while (fgets(line, FUSER_MAX_LINE, file)) {
    205         if(sscanf(line, "%*s %*s %*s %x:%x %llu",
    206             &major, &minor, &uint64_inode) != 3) continue;
     203        if (sscanf(line, "%*s %*s %*s %x:%x %llu", &major, &minor, &uint64_inode) != 3)
     204            continue;
    207205        inode = uint64_inode;
    208         if(major == 0 && minor == 0 && inode == 0) continue;
     206        if (major == 0 && minor == 0 && inode == 0)
     207            continue;
    209208        dev = makedev(major, minor);
    210         if(fuser_search_dev_inode(opts, ilist, dev, inode)) {
     209        if (fuser_search_dev_inode(opts, ilist, dev, inode)) {
    211210            fuser_add_pid(plist, pid);
    212211        }
    213 
    214212    }
    215213    fclose(file);
     
    223221    dev_t dev;
    224222
    225     if(!fuser_file_to_dev_inode(lname, &dev, &inode)) return 0;
    226     if(fuser_search_dev_inode(opts, ilist, dev, inode))
     223    if (!fuser_file_to_dev_inode(lname, &dev, &inode))
     224        return 0;
     225    if (fuser_search_dev_inode(opts, ilist, dev, inode))
    227226        fuser_add_pid(plist, pid);
    228227    return 1;
     
    236235    char *lname;
    237236
    238     if((d = opendir(dname))) {
    239         while((de = readdir(d)) != NULL) {
    240             lname = concat_subpath_file(dname, de->d_name);
    241             if(lname == NULL)
    242                 continue;
    243             fuser_scan_link(opts, lname, pid, ilist, plist);
    244             free(lname);
    245         }
    246         closedir(d);
    247     }
    248     else return 0;
    249     return 1;
    250 
     237    d = opendir(dname);
     238    if (!d)
     239        return 0;
     240    while ((de = readdir(d)) != NULL) {
     241        lname = concat_subpath_file(dname, de->d_name);
     242        if (lname == NULL)
     243            continue;
     244        fuser_scan_link(opts, lname, pid, ilist, plist);
     245        free(lname);
     246    }
     247    closedir(d);
     248    return 1;
    251249}
    252250
     
    258256    char *dname;
    259257
    260     if(!(d = opendir(FUSER_PROC_DIR))) return 0;
    261     while((de = readdir(d)) != NULL) {
     258    d = opendir(FUSER_PROC_DIR);
     259    if (!d)
     260        return 0;
     261    while ((de = readdir(d)) != NULL) {
    262262        pid = (pid_t)atoi(de->d_name);
    263         if(!pid) continue;
     263        if (!pid)
     264            continue;
    264265        dname = concat_subpath_file(FUSER_PROC_DIR, de->d_name);
    265         if(chdir(dname) < 0) {
     266        if (chdir(dname) < 0) {
    266267            free(dname);
    267268            continue;
     
    285286    pid_list *curr = plist;
    286287
    287     if(plist == NULL) return 0;
    288     while(curr != NULL) {
    289         if(curr->pid > 0) printf("%d ", curr->pid);
    290         curr = curr->next;
    291     }
    292     printf("\n");
     288    if (plist == NULL)
     289        return 0;
     290    while (curr != NULL) {
     291        if (curr->pid > 0)
     292            printf("%d ", curr->pid);
     293        curr = curr->next;
     294    }
     295    puts("");
    293296    return 1;
    294297}
     
    300303    int success = 1;
    301304
    302     if(plist == NULL) return 0;
    303     while(curr != NULL) {
    304         if(curr->pid > 0 && curr->pid != mypid) {
     305    if (plist == NULL)
     306        return 0;
     307    while (curr != NULL) {
     308        if (curr->pid > 0 && curr->pid != mypid) {
    305309            if (kill(curr->pid, sig) != 0) {
    306                 bb_perror_msg(
    307                     "Could not kill pid '%d'", curr->pid);
     310                bb_perror_msg("kill pid '%d'", curr->pid);
    308311                success = 0;
    309312            }
     
    314317}
    315318
     319int fuser_main(int argc, char **argv);
    316320int fuser_main(int argc, char **argv)
    317321{
     322    /*static -- huh???*/ int opt = 0; /* FUSER_OPT_ */
     323
    318324    int port, i, optn;
    319325    int* fni; /* file name indexes of argv */
    320326    int fnic = 0;  /* file name index count */
    321327    const char *proto;
    322     static int opt = 0; /* FUSER_OPT_ */
    323328    dev_t dev;
    324329    ino_t inode;
     
    332337
    333338    fni = xmalloc(sizeof(int));
    334     for(i=1;i<argc;i++) {
     339    for (i = 1; i < argc; i++) {
    335340        optn = fuser_option(argv[i]);
    336         if(optn) opt |= optn;
    337         else if(argv[i][0] == '-') {
    338             if(!(u_signal_names(argv[i]+1, &killsig, 0)))
     341        if (optn)
     342            opt |= optn;
     343        else if (argv[i][0] == '-') {
     344            killsig = get_signum(argv[i]+1);
     345            if (killsig < 0)
    339346                killsig = SIGTERM;
    340         }
    341         else {
     347        } else {
    342348            fni = xrealloc(fni, sizeof(int) * (fnic+2));
    343349            fni[fnic++] = i;
    344350        }
    345351    }
    346     if(!fnic) return 1;
    347 
    348     pids = xmalloc(sizeof(pid_list));
     352
     353    if (!fnic)
     354        return 1;
     355
    349356    inodes = xmalloc(sizeof(inode_list));
    350     for(i=0;i<fnic;i++) {
    351         if(fuser_parse_net_arg(argv[fni[i]], &proto, &port)) {
     357    for (i = 0; i < fnic; i++) {
     358        if (fuser_parse_net_arg(argv[fni[i]], &proto, &port)) {
    352359            fuser_scan_proc_net(opt, proto, port, inodes);
    353         }
    354         else {
    355             if(!fuser_file_to_dev_inode(
    356                 argv[fni[i]], &dev, &inode)) {
    357                 free(pids);
    358                 free(inodes);
    359                 bb_perror_msg_and_die(
    360                     "Could not open '%s'", argv[fni[i]]);
     360        } else {
     361            if (!fuser_file_to_dev_inode(argv[fni[i]], &dev, &inode)) {
     362                if (ENABLE_FEATURE_CLEAN_UP)
     363                    free(inodes);
     364                bb_perror_msg_and_die("cannot open '%s'", argv[fni[i]]);
    361365            }
    362366            fuser_add_inode(inodes, dev, inode);
    363367        }
    364368    }
     369    pids = xmalloc(sizeof(pid_list));
    365370    success = fuser_scan_proc_pids(opt, inodes, pids);
    366371    /* if the first pid in the list is 0, none have been found */
    367     if(pids->pid == 0) success = 0;
    368     if(success) {
    369         if(opt & FUSER_OPT_KILL) {
     372    if (pids->pid == 0)
     373        success = 0;
     374    if (success) {
     375        if (opt & FUSER_OPT_KILL) {
    370376            success = fuser_kill_pid_list(pids, killsig);
    371         }
    372         else if(!(opt & FUSER_OPT_SILENT)) {
     377        } else if (!(opt & FUSER_OPT_SILENT)) {
    373378            success = fuser_print_pid_list(pids);
    374379        }
    375380    }
    376     free(pids);
    377     free(inodes);
     381    if (ENABLE_FEATURE_CLEAN_UP) {
     382        free(pids);
     383        free(inodes);
     384    }
    378385    /* return 0 on (success == 1) 1 otherwise */
    379386    return (success != 1);
  • branches/2.2.5/mindi-busybox/procps/kill.c

    r821 r1765  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * Mini kill/killall implementation for busybox
     3 * Mini kill/killall[5] implementation for busybox
    44 *
    55 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
     
    99 */
    1010
    11 #include "busybox.h"
    12 #include <stdio.h>
    13 #include <stdlib.h>
    14 #include <errno.h>
    15 #include <unistd.h>
    16 #include <signal.h>
    17 #include <ctype.h>
    18 #include <string.h>
    19 #include <unistd.h>
     11#include "libbb.h"
    2012
    21 #define KILL 0
    22 #define KILLALL 1
     13/* Note: kill_main is directly called from shell in order to implement
     14 * kill built-in. Shell substitutes job ids with process groups first.
     15 *
     16 * This brings some complications:
     17 *
     18 * + we can't use xfunc here
     19 * + we can't use applet_name
     20 * + we can't use bb_show_usage
     21 * (Above doesn't apply for killall[5] cases)
     22 *
     23 * kill %n gets translated into kill ' -<process group>' by shell (note space!)
     24 * This is needed to avoid collision with kill -9 ... syntax
     25 */
    2326
     27int kill_main(int argc, char **argv);
    2428int kill_main(int argc, char **argv)
    2529{
    26     int whichApp, signo = SIGTERM;
    27     const char *name;
    28     int errors = 0;
    29 
    30 #ifdef CONFIG_KILLALL
    31     int quiet=0;
    32     /* Figure out what we are trying to do here */
    33     whichApp = (strcmp(bb_applet_name, "killall") == 0)? KILLALL : KILL;
     30    char *arg;
     31    pid_t pid;
     32    int signo = SIGTERM, errors = 0, quiet = 0;
     33#if !ENABLE_KILLALL && !ENABLE_KILLALL5
     34#define killall 0
     35#define killall5 0
    3436#else
    35     whichApp = KILL;
     37/* How to determine who we are? find 3rd char from the end:
     38 * kill, killall, killall5
     39 *  ^i       ^a        ^l  - it's unique
     40 * (checking from the start is complicated by /bin/kill... case) */
     41    const char char3 = argv[0][strlen(argv[0]) - 3];
     42#define killall (ENABLE_KILLALL && char3 == 'a')
     43#define killall5 (ENABLE_KILLALL5 && char3 == 'l')
    3644#endif
    3745
    3846    /* Parse any options */
    39     if (argc < 2)
    40         bb_show_usage();
     47    argc--;
     48    arg = *++argv;
    4149
    42     if(argv[1][0] != '-'){
    43         argv++;
    44         argc--;
     50    if (argc < 1 || arg[0] != '-') {
    4551        goto do_it_now;
    4652    }
    4753
    48     /* The -l option, which prints out signal names. */
    49     if(argv[1][1]=='l' && argv[1][2]=='\0'){
    50         if(argc==2) {
     54    /* The -l option, which prints out signal names.
     55     * Intended usage in shell:
     56     * echo "Died of SIG`kill -l $?`"
     57     * We try to mimic what kill from coreutils-6.8 does */
     58    if (arg[1] == 'l' && arg[2] == '\0') {
     59        if (argc == 1) {
    5160            /* Print the whole signal list */
    52             int col = 0;
    53             for(signo=1; signo < NSIG; signo++) {
    54                 name = u_signal_names(0, &signo, 1);
    55                 if(name==NULL)  /* unnamed */
    56                     continue;
    57                 col += printf("%2d) %-16s", signo, name);
    58                 if (col > 60) {
    59                     printf("\n");
    60                     col = 0;
     61            for (signo = 1; signo < 32; signo++) {
     62                const char *name = get_signame(signo);
     63                if (!isdigit(name[0]))
     64                    puts(name);
     65            }
     66        } else { /* -l <sig list> */
     67            while ((arg = *++argv)) {
     68                if (isdigit(arg[0])) {
     69                    signo = bb_strtou(arg, NULL, 10);
     70                    if (errno) {
     71                        bb_error_msg("unknown signal '%s'", arg);
     72                        return EXIT_FAILURE;
     73                    }
     74                    /* Exitcodes >= 0x80 are to be treated
     75                     * as "killed by signal (exitcode & 0x7f)" */
     76                    puts(get_signame(signo & 0x7f));
     77                    /* TODO: 'bad' signal# - coreutils says:
     78                     * kill: 127: invalid signal
     79                     * we just print "127" instead */
     80                } else {
     81                    signo = get_signum(arg);
     82                    if (signo < 0) {
     83                        bb_error_msg("unknown signal '%s'", arg);
     84                        return EXIT_FAILURE;
     85                    }
     86                    printf("%d\n", signo);
    6187                }
    6288            }
    63             printf("\n");
    64 
    65         } else {
    66             for(argv++; *argv; argv++) {
    67                 name = u_signal_names(*argv, &signo, -1);
    68                 if(name!=NULL)
    69                     printf("%s\n", name);
    70             }
    7189        }
    72         /* If they specified -l, were all done */
     90        /* If they specified -l, we are all done */
    7391        return EXIT_SUCCESS;
    7492    }
    7593
    76 #ifdef CONFIG_KILLALL
    7794    /* The -q quiet option */
    78     if(whichApp != KILL && argv[1][1]=='q' && argv[1][2]=='\0'){
    79         quiet++;
    80         argv++;
     95    if (killall && arg[1] == 'q' && arg[2] == '\0') {
     96        quiet = 1;
     97        arg = *++argv;
    8198        argc--;
    82         if(argc<2 || argv[1][0] != '-'){
    83             goto do_it_now;
    84         }
     99        if (argc < 1) bb_show_usage();
     100        if (arg[0] != '-') goto do_it_now;
    85101    }
    86 #endif
    87102
    88     if(!u_signal_names(argv[1]+1, &signo, 0))
    89         bb_error_msg_and_die( "bad signal name '%s'", argv[1]+1);
    90     argv+=2;
    91     argc-=2;
     103    /* -SIG */
     104    signo = get_signum(&arg[1]);
     105    if (signo < 0) { /* || signo > MAX_SIGNUM ? */
     106        bb_error_msg("bad signal name '%s'", &arg[1]);
     107        return EXIT_FAILURE;
     108    }
     109    arg = *++argv;
     110    argc--;
    92111
    93112do_it_now:
    94113
    95     /* Pid or name required */
    96     if (argc <= 0)
    97         bb_show_usage();
     114    if (killall5) {
     115        pid_t sid;
     116        procps_status_t* p = NULL;
    98117
    99     if (whichApp == KILL) {
    100         /* Looks like they want to do a kill. Do that */
    101         while (--argc >= 0) {
    102             int pid;
     118        /* Now stop all processes */
     119        kill(-1, SIGSTOP);
     120        /* Find out our own session id */
     121        pid = getpid();
     122        sid = getsid(pid);
     123        /* Now kill all processes except our session */
     124        while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID))) {
     125            if (p->sid != sid && p->pid != pid && p->pid != 1)
     126                kill(p->pid, signo);
     127        }
     128        /* And let them continue */
     129        kill(-1, SIGCONT);
     130        return 0;
     131    }
    103132
    104             if (!isdigit(**argv) && **argv != '-')
    105                 bb_error_msg_and_die( "Bad PID '%s'", *argv);
    106             pid = strtol(*argv, NULL, 0);
    107             if (kill(pid, signo) != 0) {
    108                 bb_perror_msg( "Could not kill pid '%d'", pid);
     133    /* Pid or name is required for kill/killall */
     134    if (argc < 1) {
     135        puts("You need to specify whom to kill");
     136        return EXIT_FAILURE;
     137    }
     138
     139    if (killall) {
     140        /* Looks like they want to do a killall.  Do that */
     141        pid = getpid();
     142        while (arg) {
     143            pid_t* pidList;
     144
     145            pidList = find_pid_by_name(arg);
     146            if (*pidList == 0) {
    109147                errors++;
    110             }
    111             argv++;
    112         }
     148                if (!quiet)
     149                    bb_error_msg("%s: no process killed", arg);
     150            } else {
     151                pid_t *pl;
    113152
    114     }
    115 #ifdef CONFIG_KILLALL
    116     else {
    117         pid_t myPid=getpid();
    118         /* Looks like they want to do a killall.  Do that */
    119         while (--argc >= 0) {
    120             long* pidList;
    121 
    122             pidList = find_pid_by_name(*argv);
    123             if (!pidList || *pidList<=0) {
    124                 errors++;
    125                 if (quiet==0)
    126                     bb_error_msg( "%s: no process killed", *argv);
    127             } else {
    128                 long *pl;
    129 
    130                 for(pl = pidList; *pl !=0 ; pl++) {
    131                     if (*pl==myPid)
     153                for (pl = pidList; *pl; pl++) {
     154                    if (*pl == pid)
    132155                        continue;
    133                     if (kill(*pl, signo) != 0) {
    134                         errors++;
    135                         if (quiet==0)
    136                             bb_perror_msg( "Could not kill pid '%ld'", *pl);
    137                     }
     156                    if (kill(*pl, signo) == 0)
     157                        continue;
     158                    errors++;
     159                    if (!quiet)
     160                        bb_perror_msg("cannot kill pid %u", (unsigned)*pl);
    138161                }
    139162            }
    140163            free(pidList);
    141             argv++;
     164            arg = *++argv;
    142165        }
     166        return errors;
    143167    }
    144 #endif
     168
     169    /* Looks like they want to do a kill. Do that */
     170    while (arg) {
     171        /* Support shell 'space' trick */
     172        if (arg[0] == ' ')
     173            arg++;
     174        pid = bb_strtoi(arg, NULL, 10);
     175        if (errno) {
     176            bb_error_msg("bad pid '%s'", arg);
     177            errors++;
     178        } else if (kill(pid, signo) != 0) {
     179            bb_perror_msg("cannot kill pid %d", (int)pid);
     180            errors++;
     181        }
     182        arg = *++argv;
     183    }
    145184    return errors;
    146185}
  • branches/2.2.5/mindi-busybox/procps/pidof.c

    r821 r1765  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    7  * Licensed under the GPL v2, see the file LICENSE in this tarball.
     7 * Licensed under the GPL version 2, see the file LICENSE in this tarball.
    88 */
    99
    10 #include "busybox.h"
    11 #include <stdio.h>
    12 #include <stdlib.h>
    13 #include <errno.h>
    14 #include <unistd.h>
    15 #include <signal.h>
    16 #include <ctype.h>
    17 #include <string.h>
    18 #include <sys/types.h>
    19 #include <unistd.h>
     10#include "libbb.h"
    2011
    21 #if ENABLE_FEATURE_PIDOF_SINGLE
    22 #define _SINGLE_COMPL(a) a
    23 #define SINGLE (1<<0)
    24 #else
    25 #define _SINGLE_COMPL(a)
    26 #define SINGLE (0)
    27 #endif
     12enum {
     13    USE_FEATURE_PIDOF_SINGLE(OPTBIT_SINGLE,)
     14    USE_FEATURE_PIDOF_OMIT(  OPTBIT_OMIT  ,)
     15    OPT_SINGLE = USE_FEATURE_PIDOF_SINGLE((1<<OPTBIT_SINGLE)) + 0,
     16    OPT_OMIT   = USE_FEATURE_PIDOF_OMIT(  (1<<OPTBIT_OMIT  )) + 0,
     17};
    2818
    29 #if ENABLE_FEATURE_PIDOF_OMIT
    30 #define _OMIT_COMPL(a) a
    31 #define _OMIT(a) ,a
    32 #if ENABLE_FEATURE_PIDOF_SINGLE
    33 #define OMIT (1<<1)
    34 #else
    35 #define OMIT (1<<0)
    36 #endif
    37 #else
    38 #define _OMIT_COMPL(a) ""
    39 #define _OMIT(a)
    40 #define OMIT (0)
    41 #define omitted (0)
    42 #endif
    43 
     19int pidof_main(int argc, char **argv);
    4420int pidof_main(int argc, char **argv)
    4521{
    46     unsigned n = 0;
    47     unsigned fail = 1;
    48     unsigned long int opt;
     22    unsigned first = 1;
     23    unsigned opt;
    4924#if ENABLE_FEATURE_PIDOF_OMIT
     25    char ppid_str[sizeof(int)*3 + 1];
    5026    llist_t *omits = NULL; /* list of pids to omit */
    51     bb_opt_complementally = _OMIT_COMPL("o::");
     27    opt_complementary = "o::";
    5228#endif
    5329
    5430    /* do unconditional option parsing */
    55     opt = bb_getopt_ulflags(argc, argv,
    56                     _SINGLE_COMPL("s") _OMIT_COMPL("o:")
    57                     _OMIT(&omits));
     31    opt = getopt32(argv, ""
     32            USE_FEATURE_PIDOF_SINGLE ("s")
     33            USE_FEATURE_PIDOF_OMIT("o:", &omits));
    5834
    5935#if ENABLE_FEATURE_PIDOF_OMIT
    6036    /* fill omit list.  */
    6137    {
    62         char getppid_str[32];
    63         llist_t * omits_p = omits;
     38        llist_t *omits_p = omits;
    6439        while (omits_p) {
    6540            /* are we asked to exclude the parent's process ID?  */
    66             if (!strncmp(omits_p->data, "%PPID", 5)) {
    67                 llist_pop(&omits_p);
    68                 snprintf(getppid_str, sizeof(getppid_str), "%d", getppid());
    69                 llist_add_to(&omits_p, getppid_str);
     41            if (strcmp(omits_p->data, "%PPID") == 0) {
     42                sprintf(ppid_str, "%u", (unsigned)getppid());
     43                omits_p->data = ppid_str;
    7044            }
    7145            omits_p = omits_p->link;
     
    7448#endif
    7549    /* Looks like everything is set to go.  */
    76     while(optind < argc) {
    77         long *pidList;
    78         long *pl;
     50    while (optind < argc) {
     51        pid_t *pidList;
     52        pid_t *pl;
    7953
    8054        /* reverse the pidlist like GNU pidof does.  */
    8155        pidList = pidlist_reverse(find_pid_by_name(argv[optind]));
    82         for(pl = pidList; *pl > 0; pl++) {
     56        for (pl = pidList; *pl; pl++) {
    8357#if ENABLE_FEATURE_PIDOF_OMIT
    84             unsigned omitted = 0;
    85             if (opt & OMIT) {
     58            if (opt & OPT_OMIT) {
    8659                llist_t *omits_p = omits;
    87                 while (omits_p)
    88                     if (strtol(omits_p->data, NULL, 10) == *pl) {
    89                         omitted = 1; break;
    90                     } else
    91                         omits_p = omits_p->link;
     60                while (omits_p) {
     61                    if (xatoul(omits_p->data) == *pl) {
     62                        goto omitting;
     63                    }
     64                    omits_p = omits_p->link;
     65                }
    9266            }
    9367#endif
    94             if (!omitted) {
    95                 if (n) {
    96                     putchar(' ');
    97                 } else {
    98                     n = 1;
    99                 }
    100                 printf("%ld", *pl);
    101             }
    102             fail = (!ENABLE_FEATURE_PIDOF_OMIT && omitted);
    103 
    104             if (ENABLE_FEATURE_PIDOF_SINGLE && (opt & SINGLE))
     68            printf(" %u" + first, (unsigned)*pl);
     69            first = 0;
     70            if (ENABLE_FEATURE_PIDOF_SINGLE && (opt & OPT_SINGLE))
    10571                break;
     72#if ENABLE_FEATURE_PIDOF_OMIT
     73 omitting: ;
     74#endif
    10675        }
    10776        free(pidList);
     
    11483        llist_free(omits, NULL);
    11584#endif
    116     return fail ? EXIT_FAILURE : EXIT_SUCCESS;
     85    return first; /* 1 (failure) - no processes found */
    11786}
  • branches/2.2.5/mindi-busybox/procps/ps.c

    r821 r1765  
    44 *
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
     6 * Fix for SELinux Support:(c)2007 Hiroshi Shinji <shiroshi@my.email.ne.jp>
     7                           (c)2007 Yuichi Nakamura <ynakam@hitachisoft.jp>
    68 *
    7  * Licensed under the GPL v2, see the file LICENSE in this tarball.
     9 * Licensed under the GPL version 2, see the file LICENSE in this tarball.
    810 */
    911
    10 #include "busybox.h"
    11 #include <stdio.h>
    12 #include <stdlib.h>
    13 #include <unistd.h>
    14 #include <dirent.h>
    15 #include <errno.h>
    16 #include <fcntl.h>
    17 #include <ctype.h>
    18 #include <string.h>
    19 #include <termios.h>
    20 #include <sys/ioctl.h>
    21 #if ENABLE_SELINUX
    22 #include <selinux/selinux.h>  /* for is_selinux_enabled()  */
    23 #endif
    24 
     12#include "libbb.h"
     13
     14/* Absolute maximum on output line length */
     15enum { MAX_WIDTH = 2*1024 };
     16
     17#if ENABLE_DESKTOP
     18
     19/* Print value to buf, max size+1 chars (including trailing '\0') */
     20
     21static void func_user(char *buf, int size, const procps_status_t *ps)
     22{
     23    safe_strncpy(buf, get_cached_username(ps->uid), size+1);
     24}
     25
     26static void func_comm(char *buf, int size, const procps_status_t *ps)
     27{
     28    safe_strncpy(buf, ps->comm, size+1);
     29}
     30
     31static void func_args(char *buf, int size, const procps_status_t *ps)
     32{
     33    read_cmdline(buf, size, ps->pid, ps->comm);
     34}
     35
     36static void func_pid(char *buf, int size, const procps_status_t *ps)
     37{
     38    sprintf(buf, "%*u", size, ps->pid);
     39}
     40
     41static void func_ppid(char *buf, int size, const procps_status_t *ps)
     42{
     43    sprintf(buf, "%*u", size, ps->ppid);
     44}
     45
     46static void func_pgid(char *buf, int size, const procps_status_t *ps)
     47{
     48    sprintf(buf, "%*u", size, ps->pgid);
     49}
     50
     51static void put_u(char *buf, int size, unsigned u)
     52{
     53    char buf5[5];
     54    smart_ulltoa5( ((unsigned long long)u) << 10, buf5);
     55    sprintf(buf, "%.*s", size, buf5);
     56}
     57
     58static void func_vsz(char *buf, int size, const procps_status_t *ps)
     59{
     60    put_u(buf, size, ps->vsz);
     61}
     62
     63static void func_rss(char *buf, int size, const procps_status_t *ps)
     64{
     65    put_u(buf, size, ps->rss);
     66}
     67
     68static void func_tty(char *buf, int size, const procps_status_t *ps)
     69{
     70    buf[0] = '?';
     71    buf[1] = '\0';
     72    if (ps->tty_major) /* tty field of "0" means "no tty" */
     73        snprintf(buf, size+1, "%u,%u", ps->tty_major, ps->tty_minor);
     74}
     75
     76#if ENABLE_SELINUX
     77static void func_label(char *buf, int size, const procps_status_t *ps)
     78{
     79    safe_strncpy(buf, ps->context ? ps->context : "unknown", size+1);
     80}
     81#endif
     82
     83/*
     84static void func_nice(char *buf, int size, const procps_status_t *ps)
     85{
     86    ps->???
     87}
     88
     89static void func_etime(char *buf, int size, const procps_status_t *ps)
     90{
     91    elapled time [[dd-]hh:]mm:ss
     92}
     93
     94static void func_time(char *buf, int size, const procps_status_t *ps)
     95{
     96    cumulative time [[dd-]hh:]mm:ss
     97}
     98
     99static void func_pcpu(char *buf, int size, const procps_status_t *ps)
     100{
     101}
     102*/
     103
     104typedef struct {
     105    uint16_t width;
     106    char name[6];
     107    const char *header;
     108    void (*f)(char *buf, int size, const procps_status_t *ps);
     109    int ps_flags;
     110} ps_out_t;
     111
     112static const ps_out_t out_spec[] = {
     113// Mandated by POSIX:
     114    { 8                  , "user"  ,"USER"   ,func_user  ,PSSCAN_UIDGID  },
     115    { 16                 , "comm"  ,"COMMAND",func_comm  ,PSSCAN_COMM    },
     116    { 256                , "args"  ,"COMMAND",func_args  ,PSSCAN_COMM    },
     117    { 5                  , "pid"   ,"PID"    ,func_pid   ,PSSCAN_PID     },
     118    { 5                  , "ppid"  ,"PPID"   ,func_ppid  ,PSSCAN_PPID    },
     119    { 5                  , "pgid"  ,"PGID"   ,func_pgid  ,PSSCAN_PGID    },
     120//  { sizeof("ELAPSED")-1, "etime" ,"ELAPSED",func_etime ,PSSCAN_        },
     121//  { sizeof("GROUP"  )-1, "group" ,"GROUP"  ,func_group ,PSSCAN_UIDGID  },
     122//  { sizeof("NI"     )-1, "nice"  ,"NI"     ,func_nice  ,PSSCAN_        },
     123//  { sizeof("%CPU"   )-1, "pcpu"  ,"%CPU"   ,func_pcpu  ,PSSCAN_        },
     124//  { sizeof("RGROUP" )-1, "rgroup","RGROUP" ,func_rgroup,PSSCAN_UIDGID  },
     125//  { sizeof("RUSER"  )-1, "ruser" ,"RUSER"  ,func_ruser ,PSSCAN_UIDGID  },
     126//  { sizeof("TIME"   )-1, "time"  ,"TIME"   ,func_time  ,PSSCAN_        },
     127    { 6                  , "tty"   ,"TT"     ,func_tty   ,PSSCAN_TTY     },
     128    { 4                  , "vsz"   ,"VSZ"    ,func_vsz   ,PSSCAN_VSZ     },
     129// Not mandated by POSIX, but useful:
     130    { 4                  , "rss"   ,"RSS"    ,func_rss   ,PSSCAN_RSS     },
     131#if ENABLE_SELINUX
     132    { 35                 , "label" ,"LABEL"  ,func_label ,PSSCAN_CONTEXT },
     133#endif
     134};
     135
     136#if ENABLE_SELINUX
     137#define SELINIX_O_PREFIX "label,"
     138#define DEFAULT_O_STR    SELINIX_O_PREFIX "pid,user" /* TODO: ,vsz,stat */ ",args"
     139#else
     140#define DEFAULT_O_STR    "pid,user" /* TODO: ,vsz,stat */ ",args"
     141#endif
     142
     143struct globals {
     144    ps_out_t* out;
     145    int out_cnt;
     146    int print_header;
     147    int need_flags;
     148    char *buffer;
     149    unsigned terminal_width;
     150    char default_o[sizeof(DEFAULT_O_STR)];
     151};
     152#define G (*(struct globals*)&bb_common_bufsiz1)
     153#define out            (G.out           )
     154#define out_cnt        (G.out_cnt       )
     155#define print_header   (G.print_header  )
     156#define need_flags     (G.need_flags    )
     157#define buffer         (G.buffer        )
     158#define terminal_width (G.terminal_width)
     159#define default_o      (G.default_o     )
     160
     161static ps_out_t* new_out_t(void)
     162{
     163    int i = out_cnt++;
     164    out = xrealloc(out, out_cnt * sizeof(*out));
     165    return &out[i];
     166}
     167
     168static const ps_out_t* find_out_spec(const char *name)
     169{
     170    int i;
     171    for (i = 0; i < ARRAY_SIZE(out_spec); i++) {
     172        if (!strcmp(name, out_spec[i].name))
     173            return &out_spec[i];
     174    }
     175    bb_error_msg_and_die("bad -o argument '%s'", name);
     176}
     177
     178static void parse_o(char* opt)
     179{
     180    ps_out_t* new;
     181    // POSIX: "-o is blank- or comma-separated list" (FIXME)
     182    char *comma, *equal;
     183    while (1) {
     184        comma = strchr(opt, ',');
     185        equal = strchr(opt, '=');
     186        if (comma && (!equal || equal > comma)) {
     187            *comma = '\0';
     188            *new_out_t() = *find_out_spec(opt);
     189            *comma = ',';
     190            opt = comma + 1;
     191            continue;
     192        }
     193        break;
     194    }
     195    // opt points to last spec in comma separated list.
     196    // This one can have =HEADER part.
     197    new = new_out_t();
     198    if (equal)
     199        *equal = '\0';
     200    *new = *find_out_spec(opt);
     201    if (equal) {
     202        *equal = '=';
     203        new->header = equal + 1;
     204        // POSIX: the field widths shall be ... at least as wide as
     205        // the header text (default or overridden value).
     206        // If the header text is null, such as -o user=,
     207        // the field width shall be at least as wide as the
     208        // default header text
     209        if (new->header[0]) {
     210            new->width = strlen(new->header);
     211            print_header = 1;
     212        }
     213    } else
     214        print_header = 1;
     215}
     216
     217static void post_process(void)
     218{
     219    int i;
     220    int width = 0;
     221    for (i = 0; i < out_cnt; i++) {
     222        need_flags |= out[i].ps_flags;
     223        if (out[i].header[0]) {
     224            print_header = 1;
     225        }
     226        width += out[i].width + 1; /* "FIELD " */
     227    }
     228#if ENABLE_SELINUX
     229    if (!is_selinux_enabled())
     230        need_flags &= ~PSSCAN_CONTEXT;
     231#endif
     232    buffer = xmalloc(width + 1); /* for trailing \0 */
     233}
     234
     235static void format_header(void)
     236{
     237    int i;
     238    ps_out_t* op;
     239    char *p;
     240
     241    if (!print_header)
     242        return;
     243    p = buffer;
     244    i = 0;
     245    if (out_cnt) {
     246        while (1) {
     247            op = &out[i];
     248            if (++i == out_cnt) /* do not pad last field */
     249                break;
     250            p += sprintf(p, "%-*s ", op->width, op->header);
     251        }
     252        strcpy(p, op->header);
     253    }
     254    printf("%.*s\n", terminal_width, buffer);
     255}
     256
     257static void format_process(const procps_status_t *ps)
     258{
     259    int i, len;
     260    char *p = buffer;
     261    i = 0;
     262    if (out_cnt) while (1) {
     263        out[i].f(p, out[i].width, ps);
     264        // POSIX: Any field need not be meaningful in all
     265        // implementations. In such a case a hyphen ( '-' )
     266        // should be output in place of the field value.
     267        if (!p[0]) {
     268            p[0] = '-';
     269            p[1] = '\0';
     270        }
     271        len = strlen(p);
     272        p += len;
     273        len = out[i].width - len + 1;
     274        if (++i == out_cnt) /* do not pad last field */
     275            break;
     276        p += sprintf(p, "%*s", len, "");
     277    }
     278    printf("%.*s\n", terminal_width, buffer);
     279}
     280
     281int ps_main(int argc, char **argv);
    25282int ps_main(int argc, char **argv)
    26283{
    27     procps_status_t * p;
    28     int i, len;
    29 
    30 #if ENABLE_SELINUX
    31     int use_selinux = 0;
    32     security_context_t sid=NULL;
    33 #endif
    34 
    35 #if ENABLE_FEATURE_PS_WIDE
     284    procps_status_t *p;
     285    llist_t* opt_o = NULL;
     286    USE_SELINUX(int opt;)
     287
     288    // POSIX:
     289    // -a  Write information for all processes associated with terminals
     290    //     Implementations may omit session leaders from this list
     291    // -A  Write information for all processes
     292    // -d  Write information for all processes, except session leaders
     293    // -e  Write information for all processes (equivalent to -A.)
     294    // -f  Generate a full listing
     295    // -l  Generate a long listing
     296    // -o col1,col2,col3=header
     297    //     Select which columns to display
     298    /* We allow (and ignore) most of the above. FIXME */
     299    opt_complementary = "o::";
     300    USE_SELINUX(opt =) getopt32(argv, "Zo:aAdefl", &opt_o);
     301    if (opt_o) {
     302        do {
     303            parse_o(opt_o->data);
     304            opt_o = opt_o->link;
     305        } while (opt_o);
     306    } else {
     307        /* Below: parse_o() needs char*, NOT const char*... */
     308#if ENABLE_SELINUX
     309        if (!(opt & 1) || !is_selinux_enabled()) {
     310            /* no -Z or no SELinux: do not show LABEL */
     311            strcpy(default_o, DEFAULT_O_STR + sizeof(SELINIX_O_PREFIX)-1);
     312        } else
     313#endif
     314        {
     315            strcpy(default_o, DEFAULT_O_STR);
     316        }
     317        parse_o(default_o);
     318    }
     319    post_process();
     320
     321    /* Was INT_MAX, but some libc's go belly up with printf("%.*s")
     322     * and such large widths */
     323    terminal_width = MAX_WIDTH;
     324    if (isatty(1)) {
     325        get_terminal_width_height(0, &terminal_width, NULL);
     326        if (--terminal_width > MAX_WIDTH)
     327            terminal_width = MAX_WIDTH;
     328    }
     329    format_header();
     330
     331    p = NULL;
     332    while ((p = procps_scan(p, need_flags))) {
     333        format_process(p);
     334    }
     335
     336    return EXIT_SUCCESS;
     337}
     338
     339
     340#else /* !ENABLE_DESKTOP */
     341
     342
     343int ps_main(int argc, char **argv);
     344int ps_main(int argc, char **argv)
     345{
     346    procps_status_t *p = NULL;
     347    int len;
     348    SKIP_SELINUX(const) int use_selinux = 0;
     349    USE_SELINUX(int i;)
     350#if !ENABLE_FEATURE_PS_WIDE
     351    enum { terminal_width = 79 };
     352#else
    36353    int terminal_width;
    37354    int w_count = 0;
    38 
    39     bb_opt_complementally="-:ww";
    40 #else
    41 # define terminal_width 79
    42355#endif
    43356
    44357#if ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX
    45     /* handle arguments */
    46 #if ENABLE_FEATURE_PS_WIDE && ENABLE_SELINUX
    47     i = bb_getopt_ulflags(argc, argv, "wc", &w_count);
    48 #elif ENABLE_FEATURE_PS_WIDE && !ENABLE_SELINUX
    49     bb_getopt_ulflags(argc, argv, "w", &w_count);
    50 #else /* !ENABLE_FEATURE_PS_WIDE && ENABLE_SELINUX */
    51     i = bb_getopt_ulflags(argc, argv, "c");
    52 #endif
    53358#if ENABLE_FEATURE_PS_WIDE
     359    opt_complementary = "-:ww";
     360    USE_SELINUX(i =) getopt32(argv, USE_SELINUX("Z") "w", &w_count);
    54361    /* if w is given once, GNU ps sets the width to 132,
    55362     * if w is given more than once, it is "unlimited"
    56363     */
    57     if(w_count) {
    58         terminal_width = (w_count==1) ? 132 : INT_MAX;
     364    if (w_count) {
     365        terminal_width = (w_count==1) ? 132 : MAX_WIDTH;
    59366    } else {
    60         get_terminal_width_height(1, &terminal_width, NULL);
     367        get_terminal_width_height(0, &terminal_width, NULL);
    61368        /* Go one less... */
    62         terminal_width--;
    63     }
    64 #endif
    65 #if ENABLE_SELINUX
    66     if ((i & (1+ENABLE_FEATURE_PS_WIDE)) && is_selinux_enabled())
    67         use_selinux = 1;
    68 #endif
    69 #endif  /* ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX */
    70 
    71 #if ENABLE_SELINUX
     369        if (--terminal_width > MAX_WIDTH)
     370            terminal_width = MAX_WIDTH;
     371    }
     372#else /* only ENABLE_SELINUX */
     373    i = getopt32(argv, "Z");
     374#endif
     375#if ENABLE_SELINUX
     376    if ((i & 1) && is_selinux_enabled())
     377        use_selinux = PSSCAN_CONTEXT;
     378#endif
     379#endif /* ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX */
     380
    72381    if (use_selinux)
    73       printf("  PID Context                          Stat Command\n");
     382        puts("  PID Context                          Stat Command");
    74383    else
    75 #endif
    76       printf("  PID  Uid     VmSize Stat Command\n");
    77 
    78     while ((p = procps_scan(1)) != 0)  {
    79         char *namecmd = p->cmd;
    80 #if ENABLE_SELINUX
    81         if (use_selinux)
    82           {
    83             char sbuf[128];
    84             len = sizeof(sbuf);
    85 
    86             if (is_selinux_enabled()) {
    87               if (getpidcon(p->pid,&sid)<0)
    88                 sid=NULL;
    89             }
    90 
    91             if (sid) {
    92               /*  I assume sid initilized with NULL  */
    93               len = strlen(sid)+1;
    94               safe_strncpy(sbuf, sid, len);
    95               freecon(sid);
    96               sid=NULL;
    97             }else {
    98               safe_strncpy(sbuf, "unknown",7);
    99             }
    100             len = printf("%5d %-32s %s ", p->pid, sbuf, p->state);
    101         }
    102         else
    103 #endif
    104           if(p->rss == 0)
    105             len = printf("%5d %-8s        %s ", p->pid, p->user, p->state);
    106           else
    107             len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state);
    108 
    109         i = terminal_width-len;
    110 
    111         if(namecmd && namecmd[0]) {
    112             if(i < 0)
    113                 i = 0;
    114             if(strlen(namecmd) > (size_t)i)
    115                 namecmd[i] = 0;
    116             printf("%s\n", namecmd);
    117         } else {
    118             namecmd = p->short_cmd;
    119             if(i < 2)
    120                 i = 2;
    121             if(strlen(namecmd) > ((size_t)i-2))
    122                 namecmd[i-2] = 0;
    123             printf("[%s]\n", namecmd);
    124         }
    125         /* no check needed, but to make valgrind happy..  */
    126         if (ENABLE_FEATURE_CLEAN_UP && p->cmd)
    127             free(p->cmd);
    128     }
     384        puts("  PID  Uid        VSZ Stat Command");
     385
     386    while ((p = procps_scan(p, 0
     387            | PSSCAN_PID
     388            | PSSCAN_UIDGID
     389            | PSSCAN_STATE
     390            | PSSCAN_VSZ
     391            | PSSCAN_COMM
     392            | use_selinux
     393    ))) {
     394#if ENABLE_SELINUX
     395        if (use_selinux) {
     396            len = printf("%5u %-32s %s ",
     397                    p->pid,
     398                    p->context ? p->context : "unknown",
     399                    p->state);
     400        } else
     401#endif
     402        {
     403            const char *user = get_cached_username(p->uid);
     404            if (p->vsz == 0)
     405                len = printf("%5u %-8s        %s ",
     406                    p->pid, user, p->state);
     407            else
     408                len = printf("%5u %-8s %6u %s ",
     409                    p->pid, user, p->vsz, p->state);
     410        }
     411
     412        {
     413            int sz = terminal_width - len;
     414            char buf[sz + 1];
     415            read_cmdline(buf, sz, p->pid, p->comm);
     416            puts(buf);
     417        }
     418    }
     419    if (ENABLE_FEATURE_CLEAN_UP)
     420        clear_username_cache();
    129421    return EXIT_SUCCESS;
    130422}
     423
     424#endif /* ENABLE_DESKTOP */
  • branches/2.2.5/mindi-busybox/procps/renice.c

    r821 r1765  
    2020 */
    2121
    22 #include "busybox.h"
    23 #include <stdio.h>
    24 #include <stdlib.h>
    25 #include <string.h>
    26 #include <limits.h>
    27 #include <errno.h>
    28 #include <unistd.h>
     22#include "libbb.h"
    2923#include <sys/resource.h>
    3024
    31 #if (PRIO_PROCESS < CHAR_MIN) || (PRIO_PROCESS > CHAR_MAX)
    32 #error Assumption violated : PRIO_PROCESS value
    33 #endif
    34 #if (PRIO_PGRP < CHAR_MIN) || (PRIO_PGRP > CHAR_MAX)
    35 #error Assumption violated : PRIO_PGRP value
    36 #endif
    37 #if (PRIO_USER < CHAR_MIN) || (PRIO_USER > CHAR_MAX)
    38 #error Assumption violated : PRIO_USER value
    39 #endif
     25void BUG_bad_PRIO_PROCESS(void);
     26void BUG_bad_PRIO_PGRP(void);
     27void BUG_bad_PRIO_USER(void);
    4028
    41 static inline int int_add_no_wrap(int a, int b)
    42 {
    43     int s = a + b;
    44 
    45     if (b < 0) {
    46         if (s > a) s = INT_MIN;
    47     } else {
    48         if (s < a) s = INT_MAX;
    49     }
    50 
    51     return s;
    52 }
    53 
     29int renice_main(int argc, char **argv);
    5430int renice_main(int argc, char **argv)
    5531{
    56     static const char Xetpriority_msg[] = "%d : %cetpriority";
     32    static const char Xetpriority_msg[] ALIGN1 = "%cetpriority";
    5733
    5834    int retval = EXIT_SUCCESS;
     
    6036    int use_relative = 0;
    6137    int adjustment, new_priority;
    62     id_t who;
     38    unsigned who;
     39    char *arg;
    6340
    64     ++argv;
     41    /* Yes, they are not #defines in glibc 2.4! #if won't work */
     42    if (PRIO_PROCESS < CHAR_MIN || PRIO_PROCESS > CHAR_MAX)
     43        BUG_bad_PRIO_PROCESS();
     44    if (PRIO_PGRP < CHAR_MIN || PRIO_PGRP > CHAR_MAX)
     45        BUG_bad_PRIO_PGRP();
     46    if (PRIO_USER < CHAR_MIN || PRIO_USER > CHAR_MAX)
     47        BUG_bad_PRIO_USER();
     48
     49    arg = *++argv;
    6550
    6651    /* Check if we are using a relative adjustment. */
    67     if (argv[0] && (argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) {
     52    if (arg && arg[0] == '-' && arg[1] == 'n') {
    6853        use_relative = 1;
    69         ++argv;
     54        if (!arg[2])
     55            arg = *++argv;
     56        else
     57            arg += 2;
    7058    }
    7159
    72     if (!*argv) {               /* No args?  Then show usage. */
     60    if (!arg) {             /* No args?  Then show usage. */
    7361        bb_show_usage();
    7462    }
    7563
    7664    /* Get the priority adjustment (absolute or relative). */
    77     adjustment = bb_xgetlarg(*argv, 10, INT_MIN, INT_MAX);
     65    adjustment = xatoi_range(arg, INT_MIN/2, INT_MAX/2);
    7866
    79     while (*++argv) {
     67    while ((arg = *++argv) != NULL) {
    8068        /* Check for a mode switch. */
    81         if ((argv[0][0] == '-') && argv[0][1] && !argv[0][2]) {
    82             static const char opts[]
    83                 = { 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER };
    84             const char *p;
    85             if ((p = strchr(opts, argv[0][1]))) {
     69        if (arg[0] == '-' && arg[1]) {
     70            static const char opts[] ALIGN1 = {
     71                'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER
     72            };
     73            const char *p = strchr(opts, arg[1]);
     74            if (p) {
    8675                which = p[4];
    87                 continue;
     76                if (!arg[2])
     77                    continue;
     78                arg += 2;
    8879            }
    8980        }
     
    9283        if (which == PRIO_USER) {
    9384            struct passwd *p;
    94             if (!(p = getpwnam(*argv))) {
    95                 bb_error_msg("unknown user: %s", *argv);
     85            p = getpwnam(arg);
     86            if (!p) {
     87                bb_error_msg("unknown user: %s", arg);
    9688                goto HAD_ERROR;
    9789            }
    9890            who = p->pw_uid;
    9991        } else {
    100             char *e;
    101             errno = 0;
    102             who = strtoul(*argv, &e, 10);
    103             if (*e || (*argv == e) || errno) {
    104                 bb_error_msg("bad value: %s", *argv);
     92            who = bb_strtou(arg, NULL, 10);
     93            if (errno) {
     94                bb_error_msg("bad value: %s", arg);
    10595                goto HAD_ERROR;
    10696            }
     
    114104            old_priority = getpriority(which, who);
    115105            if (errno) {
    116                 bb_perror_msg(Xetpriority_msg, who, 'g');
     106                bb_perror_msg(Xetpriority_msg, 'g');
    117107                goto HAD_ERROR;
    118108            }
    119109
    120             new_priority = int_add_no_wrap(old_priority, adjustment);
     110            new_priority = old_priority + adjustment;
    121111        } else {
    122112            new_priority = adjustment;
     
    127117        }
    128118
    129         bb_perror_msg(Xetpriority_msg, who, 's');
    130     HAD_ERROR:
     119        bb_perror_msg(Xetpriority_msg, 's');
     120 HAD_ERROR:
    131121        retval = EXIT_FAILURE;
    132122    }
  • branches/2.2.5/mindi-busybox/procps/sysctl.c

    r821 r1765  
    1515 */
    1616
    17 #include "busybox.h"
    18 #include <stdio.h>
    19 #include <stdlib.h>
    20 #include <unistd.h>
    21 #include <sys/stat.h>
    22 #include <sys/types.h>
    23 #include <dirent.h>
    24 #include <string.h>
    25 #include <errno.h>
    26 #include <fcntl.h>
     17#include "libbb.h"
    2718
    2819/*
     
    3728 *    Globals...
    3829 */
    39 static const char PROC_PATH[] = "/proc/sys/";
    40 static const char DEFAULT_PRELOAD[] = "/etc/sysctl.conf";
     30static const char PROC_PATH[] ALIGN1 = "/proc/sys/";
     31static const char DEFAULT_PRELOAD[] ALIGN1 = "/etc/sysctl.conf";
    4132
    4233/* error messages */
    43 static const char ERR_UNKNOWN_PARAMETER[] = "error: Unknown parameter '%s'\n";
    44 static const char ERR_MALFORMED_SETTING[] = "error: Malformed setting '%s'\n";
    45 static const char ERR_NO_EQUALS[] =
     34static const char ERR_UNKNOWN_PARAMETER[] ALIGN1 =
     35    "error: Unknown parameter '%s'\n";
     36static const char ERR_MALFORMED_SETTING[] ALIGN1 =
     37    "error: Malformed setting '%s'\n";
     38static const char ERR_NO_EQUALS[] ALIGN1 =
    4639    "error: '%s' must be of the form name=value\n";
    47 static const char ERR_INVALID_KEY[] = "error: '%s' is an unknown key\n";
    48 static const char ERR_UNKNOWN_WRITING[] =
     40static const char ERR_INVALID_KEY[] ALIGN1 =
     41    "error: '%s' is an unknown key\n";
     42static const char ERR_UNKNOWN_WRITING[] ALIGN1 =
    4943    "error: unknown error %d setting key '%s'\n";
    50 static const char ERR_UNKNOWN_READING[] =
     44static const char ERR_UNKNOWN_READING[] ALIGN1 =
    5145    "error: unknown error %d reading key '%s'\n";
    52 static const char ERR_PERMISSION_DENIED[] =
     46static const char ERR_PERMISSION_DENIED[] ALIGN1 =
    5347    "error: permission denied on key '%s'\n";
    54 static const char ERR_PRELOAD_FILE[] =
    55     "error: unable to open preload file '%s'\n";
    56 static const char WARN_BAD_LINE[] =
     48static const char ERR_PRELOAD_FILE[] ALIGN1 =
     49    "error: cannot open preload file '%s'\n";
     50static const char WARN_BAD_LINE[] ALIGN1 =
    5751    "warning: %s(%d): invalid syntax, continuing...\n";
    5852
     
    6660 *    sysctl_main()...
    6761 */
     62int sysctl_main(int argc, char **argv);
    6863int sysctl_main(int argc, char **argv)
    6964{
     
    139134
    140135    while (fgets(oneline, sizeof(oneline) - 1, fp)) {
    141         oneline[sizeof(oneline) - 1] = 0;
     136        oneline[sizeof(oneline) - 1] = '\0';
    142137        lineno++;
    143138        trim(oneline);
     
    166161        while ((*value == ' ' || *value == '\t') && *value != 0)
    167162            value++;
    168         strcpy(buffer, name);
    169         strcat(buffer, "=");
    170         strcat(buffer, value);
     163        /* safe because sizeof(oneline) == sizeof(buffer) */
     164        sprintf(buffer, "%s=%s", name, value);
    171165        sysctl_write_setting(buffer, output);
    172166    }
     
    203197    }
    204198
    205     tmpname = bb_xasprintf("%s%.*s", PROC_PATH, (int)(equals - name), name);
    206     outname = bb_xstrdup(tmpname + strlen(PROC_PATH));
     199    tmpname = xasprintf("%s%.*s", PROC_PATH, (int)(equals - name), name);
     200    outname = xstrdup(tmpname + strlen(PROC_PATH));
    207201
    208202    while ((cptr = strchr(tmpname, '.')) != NULL)
     
    212206        *cptr = '.';
    213207
    214     if ((fd = open(tmpname, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
     208    fd = open(tmpname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
     209    if (fd < 0) {
    215210        switch (errno) {
    216211        case ENOENT:
     
    259254
    260255    tmpname = concat_path_file(PROC_PATH, name);
    261     outname = bb_xstrdup(tmpname + strlen(PROC_PATH));
     256    outname = xstrdup(tmpname + strlen(PROC_PATH));
    262257
    263258    while ((cptr = strchr(tmpname, '.')) != NULL)
     
    310305    struct stat ts;
    311306
    312     if (!(dp = bb_opendir(path))) {
     307    dp = opendir(path);
     308    if (!dp) {
    313309        retval = -1;
    314310    } else {
    315311        while ((de = readdir(dp)) != NULL) {
    316312            tmpdir = concat_subpath_file(path, de->d_name);
    317             if(tmpdir == NULL)
     313            if (tmpdir == NULL)
    318314                continue;
    319             if ((retval2 = stat(tmpdir, &ts)) != 0)
     315            retval2 = stat(tmpdir, &ts);
     316            if (retval2 != 0)
    320317                bb_perror_msg(tmpdir);
    321318            else {
  • branches/2.2.5/mindi-busybox/procps/top.c

    r821 r1765  
    2929 */
    3030
    31 #include "busybox.h"
    32 #include <sys/types.h>
    33 #include <stdio.h>
    34 #include <stdlib.h>
    35 #include <unistd.h>
    36 #include <string.h>
    37 #include <sys/ioctl.h>
    38 
    39 //#define CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE  /* + 2k */
    40 
    41 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    42 #include <time.h>
    43 #include <fcntl.h>
    44 #include <netinet/in.h>  /* htons */
    45 #endif
    46 
    47 
    48 typedef int (*cmp_t)(procps_status_t *P, procps_status_t *Q);
    49 
    50 static procps_status_t *top;   /* Hehe */
    51 static int ntop;
    52 
    53 #ifdef CONFIG_FEATURE_USE_TERMIOS
    54 static int pid_sort(procps_status_t *P, procps_status_t *Q)
    55 {
     31#include "libbb.h"
     32
     33
     34typedef struct top_status_t {
     35    unsigned long vsz;
     36#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     37    unsigned long ticks;
     38    unsigned pcpu; /* delta of ticks */
     39#endif
     40    unsigned pid, ppid;
     41    unsigned uid;
     42    char state[4];
     43    char comm[COMM_LEN];
     44} top_status_t;
     45
     46typedef struct jiffy_counts_t {
     47    unsigned long long usr,nic,sys,idle,iowait,irq,softirq,steal;
     48    unsigned long long total;
     49    unsigned long long busy;
     50} jiffy_counts_t;
     51
     52/* This structure stores some critical information from one frame to
     53   the next. Used for finding deltas. */
     54typedef struct save_hist {
     55    unsigned long ticks;
     56    unsigned pid;
     57} save_hist;
     58
     59typedef int (*cmp_funcp)(top_status_t *P, top_status_t *Q);
     60
     61enum { SORT_DEPTH = 3 };
     62
     63struct globals {
     64    top_status_t *top;
     65    int ntop;
     66#if ENABLE_FEATURE_USE_TERMIOS
     67    struct termios initial_settings;
     68#endif
     69#if !ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     70    cmp_funcp sort_function;
     71#else
     72    cmp_funcp sort_function[SORT_DEPTH];
     73    struct save_hist *prev_hist;
     74    int prev_hist_count;
     75    jiffy_counts_t jif, prev_jif;
     76    /* int hist_iterations; */
     77    unsigned total_pcpu;
     78    /* unsigned long total_vsz; */
     79#endif
     80};
     81#define G (*(struct globals*)&bb_common_bufsiz1)
     82#define top              (G.top               )
     83#define ntop             (G.ntop              )
     84#if ENABLE_FEATURE_USE_TERMIOS
     85#define initial_settings (G. initial_settings )
     86#endif
     87#define sort_function    (G.sort_function     )
     88#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     89#define prev_hist        (G.prev_hist         )
     90#define prev_hist_count  (G.prev_hist_count   )
     91#define jif              (G.jif               )
     92#define prev_jif         (G.prev_jif          )
     93#define total_pcpu       (G.total_pcpu        )
     94#endif
     95
     96#define OPT_BATCH_MODE (option_mask32 & 0x4)
     97
     98
     99#if ENABLE_FEATURE_USE_TERMIOS
     100static int pid_sort(top_status_t *P, top_status_t *Q)
     101{
     102    /* Buggy wrt pids with high bit set */
     103    /* (linux pids are in [1..2^15-1]) */
    56104    return (Q->pid - P->pid);
    57105}
    58106#endif
    59107
    60 static int mem_sort(procps_status_t *P, procps_status_t *Q)
    61 {
    62     return (int)(Q->rss - P->rss);
    63 }
    64 
    65 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    66 
    67 #define sort_depth 3
    68 static cmp_t sort_function[sort_depth];
    69 
    70 static int pcpu_sort(procps_status_t *P, procps_status_t *Q)
    71 {
    72     return (Q->pcpu - P->pcpu);
    73 }
    74 
    75 static int time_sort(procps_status_t *P, procps_status_t *Q)
    76 {
    77     return (int)((Q->stime + Q->utime) - (P->stime + P->utime));
    78 }
    79 
    80 static int mult_lvl_cmp(void* a, void* b) {
     108static int mem_sort(top_status_t *P, top_status_t *Q)
     109{
     110    /* We want to avoid unsigned->signed and truncation errors */
     111    if (Q->vsz < P->vsz) return -1;
     112    return Q->vsz != P->vsz; /* 0 if ==, 1 if > */
     113}
     114
     115
     116#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     117
     118static int pcpu_sort(top_status_t *P, top_status_t *Q)
     119{
     120    /* Buggy wrt ticks with high bit set */
     121    /* Affects only processes for which ticks overflow */
     122    return (int)Q->pcpu - (int)P->pcpu;
     123}
     124
     125static int time_sort(top_status_t *P, top_status_t *Q)
     126{
     127    /* We want to avoid unsigned->signed and truncation errors */
     128    if (Q->ticks < P->ticks) return -1;
     129    return Q->ticks != P->ticks; /* 0 if ==, 1 if > */
     130}
     131
     132static int mult_lvl_cmp(void* a, void* b)
     133{
    81134    int i, cmp_val;
    82135
    83     for (i = 0; i < sort_depth; i++) {
     136    for (i = 0; i < SORT_DEPTH; i++) {
    84137        cmp_val = (*sort_function[i])(a, b);
    85138        if (cmp_val != 0)
     
    89142}
    90143
    91 /* This structure stores some critical information from one frame to
    92    the next. mostly used for sorting. Added cumulative and resident fields. */
    93 struct save_hist {
    94     int ticks;
    95     int pid;
    96 };
    97 
    98 /*
    99  * Calculates percent cpu usage for each task.
    100  */
    101 
    102 static struct save_hist *prev_hist;
    103 static int prev_hist_count;
    104 /* static int hist_iterations; */
    105 
    106 
    107 static unsigned total_pcpu;
    108 /* static unsigned long total_rss; */
    109 
    110 struct jiffy_counts {
    111     unsigned long long usr,nic,sys,idle,iowait,irq,softirq,steal;
    112     unsigned long long total;
    113     unsigned long long busy;
    114 };
    115 static struct jiffy_counts jif, prev_jif;
    116144
    117145static void get_jiffy_counts(void)
    118146{
    119     FILE* fp = bb_xfopen("stat", "r");
     147    FILE* fp = xfopen("stat", "r");
    120148    prev_jif = jif;
    121149    if (fscanf(fp, "cpu  %lld %lld %lld %lld %lld %lld %lld %lld",
    122150            &jif.usr,&jif.nic,&jif.sys,&jif.idle,
    123151            &jif.iowait,&jif.irq,&jif.softirq,&jif.steal) < 4) {
    124         bb_error_msg_and_die("failed to read 'stat'");
     152        bb_error_msg_and_die("failed to read /proc/stat");
    125153    }
    126154    fclose(fp);
     
    131159}
    132160
     161
    133162static void do_stats(void)
    134163{
    135     procps_status_t *cur;
    136     int pid, total_time, i, last_i, n;
     164    top_status_t *cur;
     165    pid_t pid;
     166    int i, last_i, n;
    137167    struct save_hist *new_hist;
    138168
    139169    get_jiffy_counts();
    140170    total_pcpu = 0;
    141     /* total_rss = 0; */
     171    /* total_vsz = 0; */
    142172    new_hist = xmalloc(sizeof(struct save_hist)*ntop);
    143173    /*
     
    154184         */
    155185        pid = cur->pid;
    156         total_time = cur->stime + cur->utime;
    157         new_hist[n].ticks = total_time;
     186        new_hist[n].ticks = cur->ticks;
    158187        new_hist[n].pid = pid;
    159188
     
    165194        if (prev_hist_count) do {
    166195            if (prev_hist[i].pid == pid) {
    167                 cur->pcpu = total_time - prev_hist[i].ticks;
     196                cur->pcpu = cur->ticks - prev_hist[i].ticks;
     197                total_pcpu += cur->pcpu;
    168198                break;
    169199            }
     
    171201            /* hist_iterations++; */
    172202        } while (i != last_i);
    173         total_pcpu += cur->pcpu;
    174         /* total_rss += cur->rss; */
     203        /* total_vsz += cur->vsz; */
    175204    }
    176205
     
    182211    prev_hist_count = ntop;
    183212}
    184 #else
    185 static cmp_t sort_function;
    186 #endif /* CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE */
     213#endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */
     214
     215#if ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS && ENABLE_FEATURE_TOP_DECIMALS
     216/* formats 7 char string (8 with terminating NUL) */
     217static char *fmt_100percent_8(char pbuf[8], unsigned value, unsigned total)
     218{
     219    unsigned t;
     220    if (value >= total) { /* 100% ? */
     221        strcpy(pbuf, "  100% ");
     222        return pbuf;
     223    }
     224    /* else generate " [N/space]N.N% " string */
     225    value = 1000 * value / total;
     226    t = value / 100;
     227    value = value % 100;
     228    pbuf[0] = ' ';
     229    pbuf[1] = t ? t + '0' : ' ';
     230    pbuf[2] = '0' + (value / 10);
     231    pbuf[3] = '.';
     232    pbuf[4] = '0' + (value % 10);
     233    pbuf[5] = '%';
     234    pbuf[6] = ' ';
     235    pbuf[7] = '\0';
     236    return pbuf;
     237}
     238#endif
    187239
    188240/* display generic info (meminfo / loadavg) */
     
    192244    char buf[80];
    193245    char scrbuf[80];
    194     char *end;
    195246    unsigned long total, used, mfree, shared, buffers, cached;
    196     unsigned int needs_conversion = 1;
     247#if ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS
     248    unsigned total_diff;
     249#endif
    197250
    198251    /* read memory info */
    199     fp = bb_xfopen("meminfo", "r");
     252    fp = xfopen("meminfo", "r");
    200253
    201254    /*
     
    213266
    214267        fscanf(fp, "Mem: %lu %lu %lu %lu %lu %lu",
    215            &total, &used, &mfree, &shared, &buffers, &cached);
    216     } else {
    217         /*
    218          * Revert to manual parsing, which incidentally already has the
    219          * sizes in kilobytes. This should be safe for both 2.4 and
    220          * 2.6.
    221          */
    222         needs_conversion = 0;
    223 
    224         fscanf(fp, "MemFree: %lu %s\n", &mfree, buf);
    225 
    226         /*
    227          * MemShared: is no longer present in 2.6. Report this as 0,
    228          * to maintain consistent behavior with normal procps.
    229          */
    230         if (fscanf(fp, "MemShared: %lu %s\n", &shared, buf) != 2)
    231             shared = 0;
    232 
    233         fscanf(fp, "Buffers: %lu %s\n", &buffers, buf);
    234         fscanf(fp, "Cached: %lu %s\n", &cached, buf);
    235 
    236         used = total - mfree;
    237     }
    238     fclose(fp);
    239 
    240     /* read load average as a string */
    241     fp = bb_xfopen("loadavg", "r");
    242     buf[0] = '\0';
    243     fgets(buf, sizeof(buf), fp);
    244     end = strchr(buf, ' ');
    245     if (end) end = strchr(end+1, ' ');
    246     if (end) end = strchr(end+1, ' ');
    247     if (end) *end = '\0';
    248     fclose(fp);
    249 
    250     if (needs_conversion) {
     268            &total, &used, &mfree, &shared, &buffers, &cached);
    251269        /* convert to kilobytes */
    252270        used /= 1024;
     
    256274        cached /= 1024;
    257275        total /= 1024;
    258     }
    259 
    260     /* output memory info and load average */
    261     /* clear screen & go to top */
     276    } else {
     277        /*
     278         * Revert to manual parsing, which incidentally already has the
     279         * sizes in kilobytes. This should be safe for both 2.4 and
     280         * 2.6.
     281         */
     282
     283        fscanf(fp, "MemFree: %lu %s\n", &mfree, buf);
     284
     285        /*
     286         * MemShared: is no longer present in 2.6. Report this as 0,
     287         * to maintain consistent behavior with normal procps.
     288         */
     289        if (fscanf(fp, "MemShared: %lu %s\n", &shared, buf) != 2)
     290            shared = 0;
     291
     292        fscanf(fp, "Buffers: %lu %s\n", &buffers, buf);
     293        fscanf(fp, "Cached: %lu %s\n", &cached, buf);
     294
     295        used = total - mfree;
     296    }
     297    fclose(fp);
     298
     299    /* output memory info */
    262300    if (scr_width > sizeof(scrbuf))
    263301        scr_width = sizeof(scrbuf);
    264302    snprintf(scrbuf, scr_width,
    265         "Mem: %ldK used, %ldK free, %ldK shrd, %ldK buff, %ldK cached",
     303        "Mem: %luK used, %luK free, %luK shrd, %luK buff, %luK cached",
    266304        used, mfree, shared, buffers, cached);
    267     printf("\e[H\e[J%s\n", scrbuf);
    268     snprintf(scrbuf, scr_width,
    269         "Load average: %s  (Status: S=sleeping R=running, W=waiting)", buf);
    270     printf("%s\n", scrbuf);
     305    /* clear screen & go to top */
     306    printf(OPT_BATCH_MODE ? "%s\n" : "\e[H\e[J%s\n", scrbuf);
     307
     308#if ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS
     309    /*
     310     * xxx% = (jif.xxx - prev_jif.xxx) / (jif.total - prev_jif.total) * 100%
     311     */
     312    /* using (unsigned) casts to make operations cheaper */
     313    total_diff = ((unsigned)(jif.total - prev_jif.total) ? : 1);
     314#if ENABLE_FEATURE_TOP_DECIMALS
     315/* Generated code is approx +0.3k */
     316#define CALC_STAT(xxx) char xxx[8]
     317#define SHOW_STAT(xxx) fmt_100percent_8(xxx, (unsigned)(jif.xxx - prev_jif.xxx), total_diff)
     318#define FMT "%s"
     319#else
     320#define CALC_STAT(xxx) unsigned xxx = 100 * (unsigned)(jif.xxx - prev_jif.xxx) / total_diff
     321#define SHOW_STAT(xxx) xxx
     322#define FMT "%4u%% "
     323#endif
     324    { /* need block: CALC_STAT are declarations */
     325        CALC_STAT(usr);
     326        CALC_STAT(sys);
     327        CALC_STAT(nic);
     328        CALC_STAT(idle);
     329        CALC_STAT(iowait);
     330        CALC_STAT(irq);
     331        CALC_STAT(softirq);
     332        //CALC_STAT(steal);
     333
     334        snprintf(scrbuf, scr_width,
     335            /* Barely fits in 79 chars when in "decimals" mode. */
     336            "CPU:"FMT"usr"FMT"sys"FMT"nice"FMT"idle"FMT"io"FMT"irq"FMT"softirq",
     337            SHOW_STAT(usr), SHOW_STAT(sys), SHOW_STAT(nic), SHOW_STAT(idle),
     338            SHOW_STAT(iowait), SHOW_STAT(irq), SHOW_STAT(softirq)
     339            //, SHOW_STAT(steal) - what is this 'steal' thing?
     340            // I doubt anyone wants to know it
     341        );
     342    }
     343    puts(scrbuf);
     344#undef SHOW_STAT
     345#undef CALC_STAT
     346#undef FMT
     347#endif
     348
     349    /* read load average as a string */
     350    buf[0] = '\0';
     351    open_read_close("loadavg", buf, sizeof("N.NN N.NN N.NN")-1);
     352    buf[sizeof("N.NN N.NN N.NN")-1] = '\0';
     353    snprintf(scrbuf, scr_width, "Load average: %s", buf);
     354    puts(scrbuf);
    271355
    272356    return total;
    273357}
    274 
    275358
    276359/* display process statuses */
     
    278361{
    279362    enum {
    280         bits_per_int = sizeof(int)*8
     363        BITS_PER_INT = sizeof(int)*8
    281364    };
    282365
    283     procps_status_t *s = top;
    284     char rss_str_buf[8];
    285     unsigned long total_memory = display_generic(scr_width); /* or use total_rss? */
    286     unsigned pmem_shift, pmem_scale;
    287 
    288 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    289     unsigned pcpu_shift, pcpu_scale;
     366    top_status_t *s = top;
     367    char vsz_str_buf[8];
     368    unsigned long total_memory = display_generic(scr_width); /* or use total_vsz? */
     369    /* xxx_shift and xxx_scale variables allow us to replace
     370     * expensive divides with multiply and shift */
     371    unsigned pmem_shift, pmem_scale, pmem_half;
     372#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     373    unsigned pcpu_shift, pcpu_scale, pcpu_half;
     374    unsigned busy_jifs;
    290375
    291376    /* what info of the processes is shown */
    292     printf("\e[7m%.*s\e[0m", scr_width,
    293         "  PID USER     STATUS   RSS  PPID %CPU %MEM COMMAND");
     377    printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width,
     378        "  PID  PPID USER     STAT   VSZ %MEM %CPU COMMAND");
    294379#define MIN_WIDTH \
    295     sizeof( "  PID USER     STATUS   RSS  PPID %CPU %MEM C")
    296 #else
    297     printf("\e[7m%.*s\e[0m", scr_width,
    298         "  PID USER     STATUS   RSS  PPID %MEM COMMAND");
     380    sizeof( "  PID  PPID USER     STAT   VSZ %MEM %CPU C")
     381#else
     382
     383    /* !CPU_USAGE_PERCENTAGE */
     384    printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width,
     385        "  PID  PPID USER     STAT   VSZ %MEM COMMAND");
    299386#define MIN_WIDTH \
    300     sizeof( "  PID USER     STATUS   RSS  PPID %MEM C")
    301 #endif
    302 
     387    sizeof( "  PID  PPID USER     STAT   VSZ %MEM C")
     388#endif
     389
     390#if ENABLE_FEATURE_TOP_DECIMALS
     391#define UPSCALE 1000
     392#define CALC_STAT(name, val) div_t name = div((val), 10)
     393#define SHOW_STAT(name) name.quot, '0'+name.rem
     394#define FMT "%3u.%c"
     395#else
     396#define UPSCALE 100
     397#define CALC_STAT(name, val) unsigned name = (val)
     398#define SHOW_STAT(name) name
     399#define FMT "%4u%%"
     400#endif
    303401    /*
    304      * MEM% = s->rss/MemTotal
     402     * MEM% = s->vsz/MemTotal
    305403     */
    306     pmem_shift = bits_per_int-11;
    307     pmem_scale = 1000*(1U<<(bits_per_int-11)) / total_memory;
    308     /* s->rss is in kb. we want (s->rss * pmem_scale) to never overflow */
     404    pmem_shift = BITS_PER_INT-11;
     405    pmem_scale = UPSCALE*(1U<<(BITS_PER_INT-11)) / total_memory;
     406    /* s->vsz is in kb. we want (s->vsz * pmem_scale) to never overflow */
    309407    while (pmem_scale >= 512) {
    310408        pmem_scale /= 4;
    311409        pmem_shift -= 2;
    312410    }
    313 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     411    pmem_half = (1U << pmem_shift) / (ENABLE_FEATURE_TOP_DECIMALS? 20 : 2);
     412#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     413    busy_jifs = jif.busy - prev_jif.busy;
     414    /* This happens if there were lots of short-lived processes
     415     * between two top updates (e.g. compilation) */
     416    if (total_pcpu < busy_jifs) total_pcpu = busy_jifs;
     417
    314418    /*
    315419     * CPU% = s->pcpu/sum(s->pcpu) * busy_cpu_ticks/total_cpu_ticks
     
    321425     */
    322426    pcpu_shift = 6;
    323     pcpu_scale = (1000*64*(uint16_t)(jif.busy-prev_jif.busy) ? : 1);
    324     while (pcpu_scale < (1U<<(bits_per_int-2))) {
     427    pcpu_scale = (UPSCALE*64*(uint16_t)busy_jifs ? : 1);
     428    while (pcpu_scale < (1U<<(BITS_PER_INT-2))) {
    325429        pcpu_scale *= 4;
    326430        pcpu_shift += 2;
     
    332436        pcpu_shift -= 2;
    333437    }
     438    pcpu_half = (1U << pcpu_shift) / (ENABLE_FEATURE_TOP_DECIMALS? 20 : 2);
    334439    /* printf(" pmem_scale=%u pcpu_scale=%u ", pmem_scale, pcpu_scale); */
    335440#endif
    336441
    337     while (count--) {
    338         div_t pmem = div( (s->rss*pmem_scale) >> pmem_shift, 10);
    339         int col = scr_width+1;
    340         USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE(div_t pcpu;)
    341 
    342         if (s->rss >= 100*1024)
    343             sprintf(rss_str_buf, "%6ldM", s->rss/1024);
     442    /* Ok, all prelim data is ready, go thru the list */
     443    while (count-- > 0) {
     444        int col = scr_width;
     445        CALC_STAT(pmem, (s->vsz*pmem_scale + pmem_half) >> pmem_shift);
     446#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     447        CALC_STAT(pcpu, (s->pcpu*pcpu_scale + pcpu_half) >> pcpu_shift);
     448#endif
     449
     450        if (s->vsz >= 100*1024)
     451            sprintf(vsz_str_buf, "%6ldM", s->vsz/1024);
    344452        else
    345             sprintf(rss_str_buf, "%7ld", s->rss);
    346         USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE(pcpu = div((s->pcpu*pcpu_scale) >> pcpu_shift, 10);)
    347         col -= printf("\n%5d %-8s %s  %s%6d%3u.%c" \
    348                 USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE("%3u.%c") " ",
    349                 s->pid, s->user, s->state, rss_str_buf, s->ppid,
    350                 USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE(pcpu.quot, '0'+pcpu.rem,)
    351                 pmem.quot, '0'+pmem.rem);
    352         if (col>0)
    353             printf("%.*s", col, s->short_cmd);
     453            sprintf(vsz_str_buf, "%7ld", s->vsz);
     454        // PID PPID USER STAT VSZ %MEM [%CPU] COMMAND
     455        col -= printf("\n" "%5u%6u %-8.8s %s%s" FMT
     456#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     457                FMT
     458#endif
     459                " ",
     460                s->pid, s->ppid, get_cached_username(s->uid),
     461                s->state, vsz_str_buf,
     462                SHOW_STAT(pmem)
     463#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     464                , SHOW_STAT(pcpu)
     465#endif
     466        );
     467        if (col > 0) {
     468            char buf[col + 1];
     469            read_cmdline(buf, col, s->pid, s->comm);
     470            fputs(buf, stdout);
     471        }
    354472        /* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu,
    355473            jif.busy - prev_jif.busy, jif.total - prev_jif.total); */
     
    357475    }
    358476    /* printf(" %d", hist_iterations); */
    359     putchar('\r');
     477    putchar(OPT_BATCH_MODE ? '\n' : '\r');
    360478    fflush(stdout);
    361479}
     480#undef UPSCALE
     481#undef SHOW_STAT
     482#undef CALC_STAT
     483#undef FMT
     484
    362485
    363486static void clearmems(void)
    364487{
     488    clear_username_cache();
    365489    free(top);
    366490    top = 0;
     
    368492}
    369493
    370 #ifdef CONFIG_FEATURE_USE_TERMIOS
     494
     495#if ENABLE_FEATURE_USE_TERMIOS
    371496#include <termios.h>
    372497#include <signal.h>
    373498
    374 
    375 static struct termios initial_settings;
    376 
    377499static void reset_term(void)
    378500{
    379501    tcsetattr(0, TCSANOW, (void *) &initial_settings);
    380 #ifdef CONFIG_FEATURE_CLEAN_UP
     502#if ENABLE_FEATURE_CLEAN_UP
    381503    clearmems();
    382 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     504#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    383505    free(prev_hist);
    384506#endif
    385 #endif /* CONFIG_FEATURE_CLEAN_UP */
     507#endif /* FEATURE_CLEAN_UP */
    386508}
    387509
     
    391513    exit(1);
    392514}
    393 #endif /* CONFIG_FEATURE_USE_TERMIOS */
    394 
    395 
     515#endif /* FEATURE_USE_TERMIOS */
     516
     517
     518int top_main(int argc, char **argv);
    396519int top_main(int argc, char **argv)
    397520{
    398     int opt, interval, lines, col;
    399     char *sinterval;
    400 #ifdef CONFIG_FEATURE_USE_TERMIOS
     521    int count, lines, col;
     522    unsigned interval = 5; /* default update rate is 5 seconds */
     523    unsigned iterations = UINT_MAX; /* 2^32 iterations by default :) */
     524    char *sinterval, *siterations;
     525#if ENABLE_FEATURE_USE_TERMIOS
    401526    struct termios new_settings;
    402527    struct timeval tv;
    403528    fd_set readfds;
    404529    unsigned char c;
    405 #endif /* CONFIG_FEATURE_USE_TERMIOS */
     530#endif /* FEATURE_USE_TERMIOS */
     531
     532    interval = 5;
    406533
    407534    /* do normal option parsing */
    408     opt = bb_getopt_ulflags(argc, argv, "d:", &sinterval);
    409     if ((opt & 1)) {
    410         interval = atoi(sinterval);
    411     } else {
    412         /* Default update rate is 5 seconds */
    413         interval = 5;
    414     }
     535    opt_complementary = "-";
     536    getopt32(argv, "d:n:b", &sinterval, &siterations);
     537    if (option_mask32 & 0x1) interval = xatou(sinterval); // -d
     538    if (option_mask32 & 0x2) iterations = xatou(siterations); // -n
     539    //if (option_mask32 & 0x4) // -b
    415540
    416541    /* change to /proc */
    417     bb_xchdir("/proc");
    418 #ifdef CONFIG_FEATURE_USE_TERMIOS
     542    xchdir("/proc");
     543#if ENABLE_FEATURE_USE_TERMIOS
    419544    tcgetattr(0, (void *) &initial_settings);
    420545    memcpy(&new_settings, &initial_settings, sizeof(struct termios));
    421     new_settings.c_lflag &= ~(ISIG | ICANON); /* unbuffered input */
    422     /* Turn off echoing */
    423     new_settings.c_lflag &= ~(ECHO | ECHONL);
     546    /* unbuffered input, turn off echo */
     547    new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL);
    424548
    425549    signal(SIGTERM, sig_catcher);
     
    427551    tcsetattr(0, TCSANOW, (void *) &new_settings);
    428552    atexit(reset_term);
    429 #endif /* CONFIG_FEATURE_USE_TERMIOS */
    430 
    431 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     553#endif /* FEATURE_USE_TERMIOS */
     554
     555#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    432556    sort_function[0] = pcpu_sort;
    433557    sort_function[1] = mem_sort;
     
    435559#else
    436560    sort_function = mem_sort;
    437 #endif /* CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE */
     561#endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */
    438562
    439563    while (1) {
    440         procps_status_t *p;
     564        procps_status_t *p = NULL;
    441565
    442566        /* Default to 25 lines - 5 lines for status */
    443         lines = 24 - 3;
     567        lines = 24 - 3 USE_FEATURE_TOP_CPU_GLOBAL_PERCENTS( - 1);
    444568        col = 79;
    445 #ifdef CONFIG_FEATURE_USE_TERMIOS
     569#if ENABLE_FEATURE_USE_TERMIOS
    446570        get_terminal_width_height(0, &col, &lines);
    447571        if (lines < 5 || col < MIN_WIDTH) {
     
    449573            continue;
    450574        }
    451         lines -= 3;
    452 #endif /* CONFIG_FEATURE_USE_TERMIOS */
     575        lines -= 3 USE_FEATURE_TOP_CPU_GLOBAL_PERCENTS( + 1);
     576#endif /* FEATURE_USE_TERMIOS */
    453577
    454578        /* read process IDs & status for all the processes */
    455         while ((p = procps_scan(0)) != 0) {
     579        while ((p = procps_scan(p, 0
     580                | PSSCAN_PID
     581                | PSSCAN_PPID
     582                | PSSCAN_VSZ
     583                | PSSCAN_STIME
     584                | PSSCAN_UTIME
     585                | PSSCAN_STATE
     586                | PSSCAN_COMM
     587                | PSSCAN_SID
     588                | PSSCAN_UIDGID
     589        ))) {
    456590            int n = ntop;
    457 
    458             top = xrealloc(top, (++ntop)*sizeof(procps_status_t));
    459             memcpy(top + n, p, sizeof(procps_status_t));
     591            top = xrealloc(top, (++ntop) * sizeof(*top));
     592            top[n].pid = p->pid;
     593            top[n].ppid = p->ppid;
     594            top[n].vsz = p->vsz;
     595#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     596            top[n].ticks = p->stime + p->utime;
     597#endif
     598            top[n].uid = p->uid;
     599            strcpy(top[n].state, p->state);
     600            strcpy(top[n].comm, p->comm);
    460601        }
    461602        if (ntop == 0) {
    462             bb_error_msg_and_die("Can't find process info in /proc");
     603            bb_error_msg_and_die("no process info in /proc");
    463604        }
    464 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     605#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    465606        if (!prev_hist_count) {
    466607            do_stats();
     
    470611        }
    471612        do_stats();
    472         qsort(top, ntop, sizeof(procps_status_t), (void*)mult_lvl_cmp);
    473 #else
    474         qsort(top, ntop, sizeof(procps_status_t), (void*)sort_function);
    475 #endif /* CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE */
    476         opt = lines;
    477         if (opt > ntop) {
    478             opt = ntop;
     613/* TODO: we don't need to sort all 10000 processes, we need to find top 24! */
     614        qsort(top, ntop, sizeof(top_status_t), (void*)mult_lvl_cmp);
     615#else
     616        qsort(top, ntop, sizeof(top_status_t), (void*)sort_function);
     617#endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */
     618        count = lines;
     619        if (OPT_BATCH_MODE || count > ntop) {
     620            count = ntop;
    479621        }
    480622        /* show status for each of the processes */
    481         display_status(opt, col);
    482 #ifdef CONFIG_FEATURE_USE_TERMIOS
     623        display_status(count, col);
     624#if ENABLE_FEATURE_USE_TERMIOS
    483625        tv.tv_sec = interval;
    484626        tv.tv_usec = 0;
     
    493635                break;
    494636            if (c == 'M') {
    495 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     637#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    496638                sort_function[0] = mem_sort;
    497639                sort_function[1] = pcpu_sort;
     
    501643#endif
    502644            }
    503 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     645#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    504646            if (c == 'P') {
    505647                sort_function[0] = pcpu_sort;
     
    514656#endif
    515657            if (c == 'N') {
    516 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
     658#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    517659                sort_function[0] = pid_sort;
    518660#else
     
    521663            }
    522664        }
     665        if (!--iterations)
     666            break;
    523667#else
    524668        sleep(interval);
    525 #endif /* CONFIG_FEATURE_USE_TERMIOS */
     669#endif /* FEATURE_USE_TERMIOS */
    526670        clearmems();
    527671    }
  • branches/2.2.5/mindi-busybox/procps/uptime.c

    r821 r1765  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    7  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
     7 * Licensed under the GPL version 2, see the file LICENSE in this tarball.
    88 */
    99
     
    1616/* getopt not needed */
    1717
    18 #include "busybox.h"
    19 #include <stdio.h>
    20 #include <time.h>
    21 #include <errno.h>
    22 #include <stdlib.h>
     18#include "libbb.h"
    2319
    2420#ifndef FSHIFT
     
    3026
    3127
     28int uptime_main(int argc, char **argv);
    3229int uptime_main(int argc, char **argv)
    3330{
     
    5047    uphours = (upminutes / 60) % 24;
    5148    upminutes %= 60;
    52     if(uphours)
     49    if (uphours)
    5350        printf("%2d:%02d, ", uphours, upminutes);
    5451    else
Note: See TracChangeset for help on using the changeset viewer.