X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=procps%2Fnmeter.c;h=6a3b3274382feee6d67b8e0dc7ba07816f1c6fe5;hb=b79a0fef99627c457548e804fcd6e162b116cbe8;hp=7836a90d51f2ea6e62c9c4db5c049d71f36b9b51;hpb=bdaea46318e4fe10b3fe4b20345baff2e1d69afc;p=oweals%2Fbusybox.git diff --git a/procps/nmeter.c b/procps/nmeter.c index 7836a90d5..6a3b32743 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -6,6 +6,40 @@ * Contact me: vda.linux@googlemail.com */ +//config:config NMETER +//config: bool "nmeter" +//config: default y +//config: help +//config: Prints selected system stats continuously, one line per update. + +//applet:IF_NMETER(APPLET(nmeter, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_NMETER) += nmeter.o + +//usage:#define nmeter_trivial_usage +//usage: "[-d MSEC] FORMAT_STRING" +//usage:#define nmeter_full_usage "\n\n" +//usage: "Monitor system in real time" +//usage: "\n" +//usage: "\n -d MSEC Milliseconds between updates (default:1000)" +//usage: "\n" +//usage: "\nFormat specifiers:" +//usage: "\n %Nc or %[cN] CPU. N - bar size (default:10)" +//usage: "\n (displays: S:system U:user N:niced D:iowait I:irq i:softirq)" +//usage: "\n %[nINTERFACE] Network INTERFACE" +//usage: "\n %m Allocated memory" +//usage: "\n %[mf] Free memory" +//usage: "\n %[mt] Total memory" +//usage: "\n %s Allocated swap" +//usage: "\n %f Number of used file descriptors" +//usage: "\n %Ni Total/specific IRQ rate" +//usage: "\n %x Context switch rate" +//usage: "\n %p Forks" +//usage: "\n %[pn] # of processes" +//usage: "\n %b Block io" +//usage: "\n %Nt Time (with N decimal points)" +//usage: "\n %r Print instead of at EOL" + //TODO: // simplify code // /proc/locks @@ -237,33 +271,59 @@ static int rdval_loadavg(const char* p, ullong *vec, ...) } // Parses /proc/diskstats -// 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14 +// 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14 // 3 0 hda 51292 14441 841783 926052 25717 79650 843256 3029804 0 148459 3956933 // 3 1 hda1 0 0 0 0 <- ignore if only 4 fields +// Linux 3.0 (maybe earlier) started printing full stats for hda1 too. +// Had to add code which skips such devices. static int rdval_diskstats(const char* p, ullong *vec) { - ullong rd = rd; // for compiler - int indexline = 0; + char devname[32]; + unsigned devname_len = 0; + int value_idx = 0; + vec[0] = 0; vec[1] = 0; while (1) { - indexline++; - while (*p == ' ' || *p == '\t') p++; - if (*p == '\0') break; + value_idx++; + while (*p == ' ' || *p == '\t') + p++; + if (*p == '\0') + break; if (*p == '\n') { - indexline = 0; + value_idx = 0; p++; continue; } - if (indexline == 6) { - rd = strtoull(p, NULL, 10); - } else if (indexline == 10) { - vec[0] += rd; // TODO: *sectorsize (don't know how to find out sectorsize) + if (value_idx == 3) { + char *end = strchrnul(p, ' '); + /* If this a hda1-like device (same prefix as last one + digit)? */ + if (devname_len && strncmp(devname, p, devname_len) == 0 && isdigit(p[devname_len])) { + p = end; + goto skip_line; /* skip entire line */ + } + /* It is not. Remember the name for future checks */ + devname_len = end - p; + if (devname_len > sizeof(devname)-1) + devname_len = sizeof(devname)-1; + strncpy(devname, p, devname_len); + /* devname[devname_len] = '\0'; - not really needed */ + p = end; + } else + if (value_idx == 6) { + // TODO: *sectorsize (don't know how to find out sectorsize) + vec[0] += strtoull(p, NULL, 10); + } else + if (value_idx == 10) { + // TODO: *sectorsize (don't know how to find out sectorsize) vec[1] += strtoull(p, NULL, 10); - while (*p != '\n' && *p != '\0') p++; + skip_line: + while (*p != '\n' && *p != '\0') + p++; continue; } - while (*p > ' ') p++; // skip over value + while ((unsigned char)(*p) > ' ') // skip over value + p++; } return 0; } @@ -769,6 +829,7 @@ static void FAST_FUNC collect_info(s_stat *s) typedef s_stat* init_func(const char *param); +// Deprecated %NNNd is to be removed, -d MSEC supersedes it static const char options[] ALIGN1 = "ncmsfixptbdr"; static init_func *const init_functions[] = { init_if, @@ -792,23 +853,28 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) s_stat *first = NULL; s_stat *last = NULL; s_stat *s; + char *opt_d; char *cur, *prev; INIT_G(); xchdir("/proc"); - if (!argv[1]) - bb_show_usage(); - if (open_read_close("version", buf, sizeof(buf)-1) > 0) { buf[sizeof(buf)-1] = '\0'; is26 = (strstr(buf, " 2.4.") == NULL); } - // Can use argv[1] directly, but this will mess up + if (getopt32(argv, "d:", &opt_d)) + init_delay(opt_d); + argv += optind; + + if (!argv[0]) + bb_show_usage(); + + // Can use argv[0] directly, but this will mess up // parameters as seen by e.g. ps. Making a copy... - cur = xstrdup(argv[1]); + cur = xstrdup(argv[0]); while (1) { char *param, *p; prev = cur;