Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/procps/top.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/top.c

    r3232 r3621  
    106106
    107107#include "libbb.h"
     108#include "common_bufsiz.h"
    108109
    109110
     
    184185}; //FIX_ALIASING; - large code growth
    185186enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) };
    186 #define G (*(struct globals*)&bb_common_bufsiz1)
    187 struct BUG_bad_size {
    188     char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
    189     char BUG_line_buf_too_small[LINE_BUF_SIZE > 80 ? 1 : -1];
    190 };
     187#define G (*(struct globals*)bb_common_bufsiz1)
    191188#define top              (G.top               )
    192189#define ntop             (G.ntop              )
     
    205202#define total_pcpu       (G.total_pcpu        )
    206203#define line_buf         (G.line_buf          )
    207 #define INIT_G() do { } while (0)
     204#define INIT_G() do { \
     205    setup_common_bufsiz(); \
     206    BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
     207    BUILD_BUG_ON(LINE_BUF_SIZE <= 80); \
     208} while (0)
    208209
    209210enum {
     
    265266{
    266267#if !ENABLE_FEATURE_TOP_SMP_CPU
    267     static const char fmt[] = "cpu %llu %llu %llu %llu %llu %llu %llu %llu";
     268    static const char fmt[] ALIGN1 = "cpu %llu %llu %llu %llu %llu %llu %llu %llu";
    268269#else
    269     static const char fmt[] = "cp%*s %llu %llu %llu %llu %llu %llu %llu %llu";
     270    static const char fmt[] ALIGN1 = "cp%*s %llu %llu %llu %llu %llu %llu %llu %llu";
    270271#endif
    271272    int ret;
     
    295296    prev_jif = cur_jif;
    296297    if (read_cpu_jiffy(fp, &cur_jif) < 4)
    297         bb_error_msg_and_die("can't read /proc/stat");
     298        bb_error_msg_and_die("can't read '%s'", "/proc/stat");
    298299
    299300#if !ENABLE_FEATURE_TOP_SMP_CPU
     
    500501#endif
    501502
     503enum {
     504    MI_MEMTOTAL,
     505    MI_MEMFREE,
     506    MI_MEMSHARED,
     507    MI_SHMEM,
     508    MI_BUFFERS,
     509    MI_CACHED,
     510    MI_SWAPTOTAL,
     511    MI_SWAPFREE,
     512    MI_DIRTY,
     513    MI_WRITEBACK,
     514    MI_ANONPAGES,
     515    MI_MAPPED,
     516    MI_SLAB,
     517    MI_MAX
     518};
     519
     520static void parse_meminfo(unsigned long meminfo[MI_MAX])
     521{
     522    static const char fields[] ALIGN1 =
     523        "MemTotal\0"
     524        "MemFree\0"
     525        "MemShared\0"
     526        "Shmem\0"
     527        "Buffers\0"
     528        "Cached\0"
     529        "SwapTotal\0"
     530        "SwapFree\0"
     531        "Dirty\0"
     532        "Writeback\0"
     533        "AnonPages\0"
     534        "Mapped\0"
     535        "Slab\0";
     536    char buf[60]; /* actual lines we expect are ~30 chars or less */
     537    FILE *f;
     538    int i;
     539
     540    memset(meminfo, 0, sizeof(meminfo[0]) * MI_MAX);
     541    f = xfopen_for_read("meminfo");
     542    while (fgets(buf, sizeof(buf), f) != NULL) {
     543        char *c = strchr(buf, ':');
     544        if (!c)
     545            continue;
     546        *c = '\0';
     547        i = index_in_strings(fields, buf);
     548        if (i >= 0)
     549            meminfo[i] = strtoul(c+1, NULL, 10);
     550    }
     551    fclose(f);
     552}
     553
    502554static unsigned long display_header(int scr_width, int *lines_rem_p)
    503555{
    504     FILE *fp;
    505     char buf[80];
    506     char scrbuf[80];
    507     unsigned long total, used, mfree, shared, buffers, cached;
    508 
    509     /* read memory info */
    510     fp = xfopen_for_read("meminfo");
    511 
    512     /*
    513      * Old kernels (such as 2.4.x) had a nice summary of memory info that
    514      * we could parse, however this is gone entirely in 2.6. Try parsing
    515      * the old way first, and if that fails, parse each field manually.
    516      *
    517      * First, we read in the first line. Old kernels will have bogus
    518      * strings we don't care about, whereas new kernels will start right
    519      * out with MemTotal:
    520      *                              -- PFM.
    521      */
    522     if (fscanf(fp, "MemTotal: %lu %s\n", &total, buf) != 2) {
    523         fgets(buf, sizeof(buf), fp);    /* skip first line */
    524 
    525         fscanf(fp, "Mem: %lu %lu %lu %lu %lu %lu",
    526             &total, &used, &mfree, &shared, &buffers, &cached);
    527         /* convert to kilobytes */
    528         used /= 1024;
    529         mfree /= 1024;
    530         shared /= 1024;
    531         buffers /= 1024;
    532         cached /= 1024;
    533         total /= 1024;
    534     } else {
    535         /*
    536          * Revert to manual parsing, which incidentally already has the
    537          * sizes in kilobytes. This should be safe for both 2.4 and
    538          * 2.6.
    539          */
    540         fscanf(fp, "MemFree: %lu %s\n", &mfree, buf);
    541 
    542         /*
    543          * MemShared: is no longer present in 2.6. Report this as 0,
    544          * to maintain consistent behavior with normal procps.
    545          */
    546         if (fscanf(fp, "MemShared: %lu %s\n", &shared, buf) != 2)
    547             shared = 0;
    548 
    549         fscanf(fp, "Buffers: %lu %s\n", &buffers, buf);
    550         fscanf(fp, "Cached: %lu %s\n", &cached, buf);
    551 
    552         used = total - mfree;
    553     }
    554     fclose(fp);
    555 
    556     /* output memory info */
     556    char scrbuf[100]; /* [80] was a bit too low on 8Gb ram box */
     557    char *buf;
     558    unsigned long meminfo[MI_MAX];
     559
     560    parse_meminfo(meminfo);
     561
     562    /* Output memory info */
    557563    if (scr_width > (int)sizeof(scrbuf))
    558564        scr_width = sizeof(scrbuf);
    559565    snprintf(scrbuf, scr_width,
    560566        "Mem: %luK used, %luK free, %luK shrd, %luK buff, %luK cached",
    561         used, mfree, shared, buffers, cached);
    562     /* go to top & clear to the end of screen */
     567        meminfo[MI_MEMTOTAL] - meminfo[MI_MEMFREE],
     568        meminfo[MI_MEMFREE],
     569        meminfo[MI_MEMSHARED] + meminfo[MI_SHMEM],
     570        meminfo[MI_BUFFERS],
     571        meminfo[MI_CACHED]);
     572    /* Go to top & clear to the end of screen */
    563573    printf(OPT_BATCH_MODE ? "%s\n" : "\033[H\033[J%s\n", scrbuf);
    564574    (*lines_rem_p)--;
    565575
    566     /* Display CPU time split as percentage of total time
    567      * This displays either a cumulative line or one line per CPU
     576    /* Display CPU time split as percentage of total time.
     577     * This displays either a cumulative line or one line per CPU.
    568578     */
    569579    display_cpus(scr_width, scrbuf, lines_rem_p);
    570580
    571     /* read load average as a string */
    572     buf[0] = '\0';
    573     open_read_close("loadavg", buf, sizeof(buf) - 1);
    574     buf[sizeof(buf) - 1] = '\n';
    575     *strchr(buf, '\n') = '\0';
    576     snprintf(scrbuf, scr_width, "Load average: %s", buf);
     581    /* Read load average as a string */
     582    buf = stpcpy(scrbuf, "Load average: ");
     583    open_read_close("loadavg", buf, sizeof(scrbuf) - sizeof("Load average: "));
     584    scrbuf[scr_width - 1] = '\0';
     585    strchrnul(buf, '\n')[0] = '\0';
    577586    puts(scrbuf);
    578587    (*lines_rem_p)--;
    579588
    580     return total;
     589    return meminfo[MI_MEMTOTAL];
    581590}
    582591
     
    678687            sprintf(vsz_str_buf, "%6ldm", s->vsz/1024);
    679688        else
    680             sprintf(vsz_str_buf, "%7ld", s->vsz);
     689            sprintf(vsz_str_buf, "%7lu", s->vsz);
    681690        /* PID PPID USER STAT VSZ %VSZ [%CPU] COMMAND */
    682691        col = snprintf(line_buf, scr_width,
     
    782791static void display_topmem_header(int scr_width, int *lines_rem_p)
    783792{
    784     enum {
    785         TOTAL = 0, MFREE, BUF, CACHE,
    786         SWAPTOTAL, SWAPFREE, DIRTY,
    787         MWRITE, ANON, MAP, SLAB,
    788         NUM_FIELDS
    789     };
    790     static const char match[NUM_FIELDS][12] = {
    791         "\x09" "MemTotal:",  // TOTAL
    792         "\x08" "MemFree:",   // MFREE
    793         "\x08" "Buffers:",   // BUF
    794         "\x07" "Cached:",    // CACHE
    795         "\x0a" "SwapTotal:", // SWAPTOTAL
    796         "\x09" "SwapFree:",  // SWAPFREE
    797         "\x06" "Dirty:",     // DIRTY
    798         "\x0a" "Writeback:", // MWRITE
    799         "\x0a" "AnonPages:", // ANON
    800         "\x07" "Mapped:",    // MAP
    801         "\x05" "Slab:",      // SLAB
    802     };
    803     char meminfo_buf[4 * 1024];
    804     const char *Z[NUM_FIELDS];
    805     unsigned i;
    806     int sz;
    807 
    808     for (i = 0; i < NUM_FIELDS; i++)
    809         Z[i] = "?";
    810 
    811     /* read memory info */
    812     sz = open_read_close("meminfo", meminfo_buf, sizeof(meminfo_buf) - 1);
    813     if (sz >= 0) {
    814         char *p = meminfo_buf;
    815         meminfo_buf[sz] = '\0';
    816         /* Note that fields always appear in the match[] order */
    817         for (i = 0; i < NUM_FIELDS; i++) {
    818             char *found = strstr(p, match[i] + 1);
    819             if (found) {
    820                 /* Cut "NNNN" out of "    NNNN kb" */
    821                 char *s = skip_whitespace(found + match[i][0]);
    822                 p = skip_non_whitespace(s);
    823                 *p++ = '\0';
    824                 Z[i] = s;
    825             }
    826         }
    827     }
     793    unsigned long meminfo[MI_MAX];
     794
     795    parse_meminfo(meminfo);
    828796
    829797    snprintf(line_buf, LINE_BUF_SIZE,
    830         "Mem total:%s anon:%s map:%s free:%s",
    831         Z[TOTAL], Z[ANON], Z[MAP], Z[MFREE]);
     798        "Mem total:%lu anon:%lu map:%lu free:%lu",
     799        meminfo[MI_MEMTOTAL],
     800        meminfo[MI_ANONPAGES],
     801        meminfo[MI_MAPPED],
     802        meminfo[MI_MEMFREE]);
    832803    printf(OPT_BATCH_MODE ? "%.*s\n" : "\033[H\033[J%.*s\n", scr_width, line_buf);
    833804
    834805    snprintf(line_buf, LINE_BUF_SIZE,
    835         " slab:%s buf:%s cache:%s dirty:%s write:%s",
    836         Z[SLAB], Z[BUF], Z[CACHE], Z[DIRTY], Z[MWRITE]);
     806        " slab:%lu buf:%lu cache:%lu dirty:%lu write:%lu",
     807        meminfo[MI_SLAB],
     808        meminfo[MI_BUFFERS],
     809        meminfo[MI_CACHED],
     810        meminfo[MI_DIRTY],
     811        meminfo[MI_WRITEBACK]);
    837812    printf("%.*s\n", scr_width, line_buf);
    838813
    839814    snprintf(line_buf, LINE_BUF_SIZE,
    840         "Swap total:%s free:%s", // TODO: % used?
    841         Z[SWAPTOTAL], Z[SWAPFREE]);
     815        "Swap total:%lu free:%lu", // TODO: % used?
     816        meminfo[MI_SWAPTOTAL],
     817        meminfo[MI_SWAPFREE]);
    842818    printf("%.*s\n", scr_width, line_buf);
    843819
     
    848824{
    849825    /* see http://en.wikipedia.org/wiki/Tera */
    850     smart_ulltoa5(ul, buf, " mgtpezy");
    851     buf[5] = ' ';
     826    smart_ulltoa5(ul, buf, " mgtpezy")[0] = ' ';
    852827}
    853828
     
    857832#define MIN_WIDTH sizeof(HDR_STR)
    858833    const topmem_status_t *s = topmem + G_scroll_ofs;
     834    char *cp, ch;
    859835
    860836    display_topmem_header(scr_width, &lines_rem);
     837
    861838    strcpy(line_buf, HDR_STR " COMMAND");
    862     line_buf[11 + sort_field * 6] = "^_"[inverted];
     839    /* Mark the ^FIELD^ we sort by */
     840    cp = &line_buf[5 + sort_field * 6];
     841    ch = "^_"[inverted];
     842    cp[6] = ch;
     843    do *cp++ = ch; while (*cp == ' ');
     844
    863845    printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width, line_buf);
    864846    lines_rem--;
     
    919901static unsigned handle_input(unsigned scan_mask, unsigned interval)
    920902{
    921     struct pollfd pfd[1];
    922 
    923903    if (option_mask32 & OPT_EOF) {
    924904        /* EOF on stdin ("top </dev/null") */
     
    926906        return scan_mask;
    927907    }
    928 
    929     pfd[0].fd = 0;
    930     pfd[0].events = POLLIN;
    931908
    932909    while (1) {
     
    12051182        while ((p = procps_scan(p, scan_mask)) != NULL) {
    12061183            int n;
    1207 #if ENABLE_FEATURE_TOPMEM
    1208             if (scan_mask != TOPMEM_MASK)
    1209 #endif
    1210             {
     1184
     1185            IF_FEATURE_TOPMEM(if (scan_mask != TOPMEM_MASK)) {
    12111186                n = ntop;
    12121187                top = xrealloc_vector(top, 6, ntop++);
     
    12481223        }
    12491224
    1250         if (scan_mask != TOPMEM_MASK) {
     1225        IF_FEATURE_TOPMEM(if (scan_mask != TOPMEM_MASK)) {
    12511226#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
    12521227            if (!prev_hist_count) {
     
    12621237            qsort(top, ntop, sizeof(top_status_t), (void*)(sort_function[0]));
    12631238#endif
     1239            display_process_list(G.lines, col);
    12641240        }
    12651241#if ENABLE_FEATURE_TOPMEM
    12661242        else { /* TOPMEM */
    12671243            qsort(topmem, ntop, sizeof(topmem_status_t), (void*)topmem_sort);
    1268         }
    1269 #endif
    1270         if (scan_mask != TOPMEM_MASK)
    1271             display_process_list(G.lines, col);
    1272 #if ENABLE_FEATURE_TOPMEM
    1273         else
    12741244            display_topmem_process_list(G.lines, col);
     1245        }
    12751246#endif
    12761247        clearmems();
     
    12811252#else
    12821253        scan_mask = handle_input(scan_mask, interval);
    1283 #endif /* FEATURE_USE_TERMIOS */
     1254#endif
    12841255    } /* end of "while (not Q)" */
    12851256
Note: See TracChangeset for help on using the changeset viewer.