Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/procps/nmeter.c


Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/3.3/mindi-busybox/procps/nmeter.c

    r3232 r3621  
    2222//usage:       "Monitor system in real time"
    2323//usage:     "\n"
    24 //usage:     "\n -d MSEC    Milliseconds between updates (default:1000)"
     24//usage:     "\n -d MSEC    Milliseconds between updates, default:1000, none:-1"
    2525//usage:     "\n"
    2626//usage:     "\nFormat specifiers:"
     
    5454
    5555#include "libbb.h"
     56#include "common_bufsiz.h"
    5657
    5758typedef unsigned long long ullong;
     
    8485    // 1 if sample delay is not an integer fraction of a second
    8586    smallint need_seconds;
     87    char final_char;
    8688    char *cur_outbuf;
    87     const char *final_str;
    8889    int delta;
    89     int deltanz;
     90    unsigned deltanz;
    9091    struct timeval tv;
    9192#define first_proc_file proc_stat
     
    102103#define need_seconds       (G.need_seconds      )
    103104#define cur_outbuf         (G.cur_outbuf        )
    104 #define final_str          (G.final_str         )
    105 #define delta              (G.delta             )
    106 #define deltanz            (G.deltanz           )
    107105#define tv                 (G.tv                )
    108106#define proc_stat          (G.proc_stat         )
     
    112110#define proc_diskstats     (G.proc_diskstats    )
    113111#define proc_sys_fs_filenr (G.proc_sys_fs_filenr)
     112#define outbuf bb_common_bufsiz1
    114113#define INIT_G() do { \
     114    setup_common_bufsiz(); \
    115115    SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
    116116    cur_outbuf = outbuf; \
    117     final_str = "\n"; \
    118     deltanz = delta = 1000000; \
     117    G.final_char = '\n'; \
     118    G.deltanz = G.delta = 1000000; \
    119119} while (0)
    120 
    121 // We depend on this being a char[], not char* - we take sizeof() of it
    122 #define outbuf bb_common_bufsiz1
    123120
    124121static inline void reset_outbuf(void)
     
    143140static void put(const char *s)
    144141{
    145     int sz = strlen(s);
    146     if (sz > outbuf + sizeof(outbuf) - cur_outbuf)
    147         sz = outbuf + sizeof(outbuf) - cur_outbuf;
    148     memcpy(cur_outbuf, s, sz);
    149     cur_outbuf += sz;
     142    char *p = cur_outbuf;
     143    int sz = outbuf + COMMON_BUFSIZE - p;
     144    while (*s && --sz >= 0)
     145        *p++ = *s++;
     146    cur_outbuf = p;
    150147}
    151148
    152149static void put_c(char c)
    153150{
    154     if (cur_outbuf < outbuf + sizeof(outbuf))
     151    if (cur_outbuf < outbuf + COMMON_BUFSIZE)
    155152        *cur_outbuf++ = c;
    156153}
     
    209206}
    210207
    211 enum conv_type { conv_decimal, conv_slash };
     208enum conv_type {
     209    conv_decimal = 0,
     210    conv_slash = 1
     211};
    212212
    213213// Reads decimal values from line. Values start after key, for example:
    214214// "cpu  649369 0 341297 4336769..." - key is "cpu" here.
    215 // Values are stored in vec[]. arg_ptr has list of positions
    216 // we are interested in: for example: 1,2,5 - we want 1st, 2nd and 5th value.
    217 static int vrdval(const char* p, const char* key,
    218     enum conv_type conv, ullong *vec, va_list arg_ptr)
    219 {
    220     int indexline;
    221     int indexnext;
     215// Values are stored in vec[].
     216// posbits is a bit lit of positions we are interested in.
     217// for example: 00100110 - we want 1st, 2nd and 5th value.
     218// posbits.bit0 encodes conversion type.
     219static int rdval(const char* p, const char* key, ullong *vec, long posbits)
     220{
     221    unsigned curpos;
    222222
    223223    p = strstr(p, key);
     
    225225
    226226    p += strlen(key);
    227     indexline = 1;
    228     indexnext = va_arg(arg_ptr, int);
     227    curpos = 1 << 1;
    229228    while (1) {
    230229        while (*p == ' ' || *p == '\t') p++;
    231230        if (*p == '\n' || *p == '\0') break;
    232231
    233         if (indexline == indexnext) { // read this value
    234             *vec++ = conv==conv_decimal ?
     232        if (curpos & posbits) { // read this value
     233            *vec++ = (posbits & 1) == conv_decimal ?
    235234                strtoull(p, NULL, 10) :
    236235                read_after_slash(p);
    237             indexnext = va_arg(arg_ptr, int);
     236            posbits -= curpos;
     237            if (posbits <= 1)
     238                return 0;
    238239        }
    239         while (*p > ' ') p++; // skip over value
    240         indexline++;
     240        while (*p > ' ') // skip over the value
     241            p++;
     242        curpos <<= 1;
    241243    }
    242244    return 0;
    243245}
    244246
    245 // Parses files with lines like "cpu0 21727 0 15718 1813856 9461 10485 0 0":
    246 // rdval(file_contents, "string_to_find", result_vector, value#, value#...)
    247 // value# start with 1
    248 static int rdval(const char* p, const char* key, ullong *vec, ...)
    249 {
    250     va_list arg_ptr;
     247// Parses files with lines like "... ... ... 3/148 ...."
     248static int rdval_loadavg(const char* p, ullong *vec, long posbits)
     249{
    251250    int result;
    252 
    253     va_start(arg_ptr, vec);
    254     result = vrdval(p, key, conv_decimal, vec, arg_ptr);
    255     va_end(arg_ptr);
    256 
    257     return result;
    258 }
    259 
    260 // Parses files with lines like "... ... ... 3/148 ...."
    261 static int rdval_loadavg(const char* p, ullong *vec, ...)
    262 {
    263     va_list arg_ptr;
    264     int result;
    265 
    266     va_start(arg_ptr, vec);
    267     result = vrdval(p, "", conv_slash, vec, arg_ptr);
    268     va_end(arg_ptr);
    269 
     251    result = rdval(p, "", vec, posbits | conv_slash);
    270252    return result;
    271253}
     
    334316
    335317    /* see http://en.wikipedia.org/wiki/Tera */
    336     smart_ulltoa4(ul, buf, " kmgtpezy");
    337     buf[4] = '\0';
     318    smart_ulltoa4(ul, buf, " kmgtpezy")[0] = '\0';
    338319    put(buf);
    339320}
    340 
    341321
    342322#define S_STAT(a) \
     
    361341}
    362342
    363 static s_stat* init_delay(const char *param)
    364 {
    365     delta = strtoul(param, NULL, 0) * 1000; /* param can be "" */
    366     deltanz = delta > 0 ? delta : 1;
    367     need_seconds = (1000000%deltanz) != 0;
     343static s_stat* init_cr(const char *param UNUSED_PARAM)
     344{
     345    G.final_char = '\r';
    368346    return NULL;
    369347}
    370 
    371 static s_stat* init_cr(const char *param UNUSED_PARAM)
    372 {
    373     final_str = "\r";
    374     return (s_stat*)0;
    375 }
    376 
    377348
    378349//     user nice system idle  iowait irq  softirq (last 3 only in 2.6)
     
    383354    ullong old[CPU_FIELDCNT];
    384355    int bar_sz;
    385     char *bar;
     356    char bar[1];
    386357S_STAT_END(cpu_stat)
    387 
    388358
    389359static void FAST_FUNC collect_cpu(cpu_stat *s)
     
    397367    int i;
    398368
    399     if (rdval(get_file(&proc_stat), "cpu ", data, 1, 2, 3, 4, 5, 6, 7)) {
     369    if (rdval(get_file(&proc_stat), "cpu ", data, 0
     370        | (1 << 1)
     371        | (1 << 2)
     372        | (1 << 3)
     373        | (1 << 4)
     374        | (1 << 5)
     375        | (1 << 6)
     376        | (1 << 7))
     377    ) {
    400378        put_question_marks(bar_sz);
    401379        return;
     
    440418}
    441419
    442 
    443420static s_stat* init_cpu(const char *param)
    444421{
    445422    int sz;
    446     cpu_stat *s = xzalloc(sizeof(*s));
    447     s->collect = collect_cpu;
     423    cpu_stat *s;
    448424    sz = strtoul(param, NULL, 0); /* param can be "" */
    449425    if (sz < 10) sz = 10;
    450426    if (sz > 1000) sz = 1000;
    451     s->bar = xzalloc(sz+1);
     427    s = xzalloc(sizeof(*s) + sz);
    452428    /*s->bar[sz] = '\0'; - xzalloc did it */
    453429    s->bar_sz = sz;
    454     return (s_stat*)s;
    455 }
    456 
     430    s->collect = collect_cpu;
     431    return (s_stat*)s;
     432}
    457433
    458434S_STAT(int_stat)
     
    466442    ullong old;
    467443
    468     if (rdval(get_file(&proc_stat), "intr", data, s->no)) {
     444    if (rdval(get_file(&proc_stat), "intr", data, 1 << s->no)) {
    469445        put_question_marks(4);
    470446        return;
     
    490466}
    491467
    492 
    493468S_STAT(ctx_stat)
    494469    ullong old;
     
    500475    ullong old;
    501476
    502     if (rdval(get_file(&proc_stat), "ctxt", data, 1)) {
     477    if (rdval(get_file(&proc_stat), "ctxt", data, 1 << 1)) {
    503478        put_question_marks(4);
    504479        return;
     
    518493}
    519494
    520 
    521495S_STAT(blk_stat)
    522496    const char* lookfor;
     
    532506        i = rdval_diskstats(get_file(&proc_diskstats), data);
    533507    } else {
    534         i = rdval(get_file(&proc_stat), s->lookfor, data, 1, 2);
     508        i = rdval(get_file(&proc_stat), s->lookfor, data, 0
     509                | (1 << 1)
     510                | (1 << 2)
     511        );
    535512        // Linux 2.4 reports bio in Kbytes, convert to sectors:
    536513        data[0] *= 2;
     
    561538}
    562539
    563 
    564540S_STAT(fork_stat)
    565541    ullong old;
     
    570546    ullong data[1];
    571547
    572     if (rdval_loadavg(get_file(&proc_loadavg), data, 4)) {
     548    if (rdval_loadavg(get_file(&proc_loadavg), data, 1 << 4)) {
    573549        put_question_marks(4);
    574550        return;
     
    582558    ullong old;
    583559
    584     if (rdval(get_file(&proc_stat), "processes", data, 1)) {
     560    if (rdval(get_file(&proc_stat), "processes", data, 1 << 1)) {
    585561        put_question_marks(4);
    586562        return;
     
    604580}
    605581
    606 
    607582S_STAT(if_stat)
    608583    ullong old[4];
     
    616591    int i;
    617592
    618     if (rdval(get_file(&proc_net_dev), s->device_colon, data, 1, 3, 9, 11)) {
     593    if (rdval(get_file(&proc_net_dev), s->device_colon, data, 0
     594        | (1 << 1)
     595        | (1 << 3)
     596        | (1 << 9)
     597        | (1 << 11))
     598    ) {
    619599        put_question_marks(10);
    620600        return;
     
    645625    return (s_stat*)s;
    646626}
    647 
    648627
    649628S_STAT(mem_stat)
     
    694673    ullong m_slab = 0;
    695674
    696     if (rdval(get_file(&proc_meminfo), "MemTotal:", &m_total, 1)) {
     675    if (rdval(get_file(&proc_meminfo), "MemTotal:", &m_total, 1 << 1)) {
    697676        put_question_marks(4);
    698677        return;
     
    703682    }
    704683
    705     if (rdval(proc_meminfo.file, "MemFree:", &m_free  , 1)
    706      || rdval(proc_meminfo.file, "Buffers:", &m_bufs  , 1)
    707      || rdval(proc_meminfo.file, "Cached:",  &m_cached, 1)
    708      || rdval(proc_meminfo.file, "Slab:",    &m_slab  , 1)
     684    if (rdval(proc_meminfo.file, "MemFree:", &m_free  , 1 << 1)
     685     || rdval(proc_meminfo.file, "Buffers:", &m_bufs  , 1 << 1)
     686     || rdval(proc_meminfo.file, "Cached:",  &m_cached, 1 << 1)
     687     || rdval(proc_meminfo.file, "Slab:",    &m_slab  , 1 << 1)
    709688    ) {
    710689        put_question_marks(4);
     
    729708}
    730709
    731 
    732710S_STAT(swp_stat)
    733711S_STAT_END(swp_stat)
     
    737715    ullong s_total[1];
    738716    ullong s_free[1];
    739     if (rdval(get_file(&proc_meminfo), "SwapTotal:", s_total, 1)
    740      || rdval(proc_meminfo.file,       "SwapFree:" , s_free,  1)
     717    if (rdval(get_file(&proc_meminfo), "SwapTotal:", s_total, 1 << 1)
     718     || rdval(proc_meminfo.file,       "SwapFree:" , s_free,  1 << 1)
    741719    ) {
    742720        put_question_marks(4);
     
    753731}
    754732
    755 
    756733S_STAT(fd_stat)
    757734S_STAT_END(fd_stat)
     
    761738    ullong data[2];
    762739
    763     if (rdval(get_file(&proc_sys_fs_filenr), "", data, 1, 2)) {
     740    if (rdval(get_file(&proc_sys_fs_filenr), "", data, 0
     741        | (1 << 1)
     742        | (1 << 2))
     743    ) {
    764744        put_question_marks(4);
    765745        return;
     
    776756}
    777757
    778 
    779758S_STAT(time_stat)
    780     int prec;
    781     int scale;
     759    unsigned prec;
     760    unsigned scale;
    782761S_STAT_END(time_stat)
    783762
     
    786765    char buf[sizeof("12:34:56.123456")];
    787766    struct tm* tm;
    788     int us = tv.tv_usec + s->scale/2;
     767    unsigned us = tv.tv_usec + s->scale/2;
    789768    time_t t = tv.tv_sec;
    790769
     
    827806}
    828807
    829 
    830808typedef s_stat* init_func(const char *param);
    831809
    832 // Deprecated %NNNd is to be removed, -d MSEC supersedes it
    833 static const char options[] ALIGN1 = "ncmsfixptbdr";
     810static const char options[] ALIGN1 = "ncmsfixptbr";
    834811static init_func *const init_functions[] = {
    835812    init_if,
     
    843820    init_time,
    844821    init_blk,
    845     init_delay,
    846822    init_cr
    847823};
     
    866842    }
    867843
    868     if (getopt32(argv, "d:", &opt_d))
    869         init_delay(opt_d);
     844    if (getopt32(argv, "d:", &opt_d)) {
     845        G.delta = xatoi(opt_d) * 1000;
     846        G.deltanz = G.delta > 0 ? G.delta : 1;
     847        need_seconds = (1000000 % G.deltanz) != 0;
     848    }
    870849    argv += optind;
    871850
     
    922901            last = s;
    923902        } else {
    924             // %NNNNd or %r option. remove it from string
    925             strcpy(prev + strlen(prev), cur);
     903            // %r option. remove it from string
     904            overlapping_strcpy(prev + strlen(prev), cur);
    926905            cur = prev;
    927906        }
     
    941920    collect_info(first);
    942921    reset_outbuf();
    943     if (delta >= 0) {
     922    if (G.delta >= 0) {
    944923        gettimeofday(&tv, NULL);
    945         usleep(delta > 1000000 ? 1000000 : delta - tv.tv_usec%deltanz);
     924        usleep(G.delta > 1000000 ? 1000000 : G.delta - tv.tv_usec % G.deltanz);
    946925    }
    947926
     
    949928        gettimeofday(&tv, NULL);
    950929        collect_info(first);
    951         put(final_str);
     930        put_c(G.final_char);
    952931        print_outbuf();
    953932
     
    957936        // TODO: detect and avoid useless updates
    958937        // (like: nothing happens except time)
    959         if (delta >= 0) {
     938        if (G.delta >= 0) {
    960939            int rem;
    961940            // can be commented out, will sacrifice sleep time precision a bit
    962941            gettimeofday(&tv, NULL);
    963942            if (need_seconds)
    964                 rem = delta - ((ullong)tv.tv_sec*1000000 + tv.tv_usec) % deltanz;
     943                rem = G.delta - ((ullong)tv.tv_sec*1000000 + tv.tv_usec) % G.deltanz;
    965944            else
    966                 rem = delta - tv.tv_usec%deltanz;
     945                rem = G.delta - (unsigned)tv.tv_usec % G.deltanz;
    967946            // Sometimes kernel wakes us up just a tiny bit earlier than asked
    968947            // Do not go to very short sleep in this case
    969             if (rem < delta/128) {
    970                 rem += delta;
     948            if (rem < (unsigned)G.delta / 128) {
     949                rem += G.delta;
    971950            }
    972951            usleep(rem);
Note: See TracChangeset for help on using the changeset viewer.