aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--procps/top.c60
1 files changed, 27 insertions, 33 deletions
diff --git a/procps/top.c b/procps/top.c
index 51b167171..04dd82633 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -103,11 +103,11 @@ struct globals {
}; //FIX_ALIASING; - large code growth
enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) };
#define G (*(struct globals*)&bb_common_bufsiz1)
-#define INIT_G() do { \
- struct G_sizecheck { \
- char G_sizecheck[sizeof(G) > COMMON_BUFSIZE ? -1 : 1]; \
- }; \
-} while (0)
+struct BUG_bad_size {
+ char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
+ char BUG_line_buf_too_small[LINE_BUF_SIZE > 80 ? 1 : -1];
+};
+#define INIT_G() do { } while (0)
#define top (G.top )
#define ntop (G.ntop )
#define sort_field (G.sort_field )
@@ -705,7 +705,7 @@ static void display_topmem_header(int scr_width, int *lines_rem_p)
MWRITE, ANON, MAP, SLAB,
NUM_FIELDS
};
- static const char match[NUM_FIELDS][11] = {
+ static const char match[NUM_FIELDS][12] = {
"\x09" "MemTotal:", // TOTAL
"\x08" "MemFree:", // MFREE
"\x08" "Buffers:", // BUF
@@ -718,52 +718,46 @@ static void display_topmem_header(int scr_width, int *lines_rem_p)
"\x07" "Mapped:", // MAP
"\x05" "Slab:", // SLAB
};
-//TODO? Note that fields always appear in the above order.
-//Thus, as each new line read from /proc/meminfo, we can compare it *once*
-//with match[last_matched+1], instead of looping thru all match[i]'s.
-//If it matches, memorize its data and last_matched++ (and if == NUM_FIELDS,
-//we're done with reading /proc/meminfo!); otherwise fgets next line.
-//The code below is slower, but is robust against a case when /proc/meminfo
-//gets reordered in the future.
- char Z[NUM_FIELDS][sizeof(long long)*3];
- char linebuf[128];
+ char meminfo_buf[4 * 1024];
+ const char *Z[NUM_FIELDS];
unsigned i;
- FILE *fp;
+ int sz;
- memset(&Z, 0, sizeof(Z));
for (i = 0; i < NUM_FIELDS; i++)
- Z[i][0] = '?';
+ Z[i] = "?";
/* read memory info */
- fp = xfopen_for_read("meminfo");
- while (fgets(linebuf, sizeof(linebuf), fp)) {
+ sz = open_read_close("meminfo", meminfo_buf, sizeof(meminfo_buf) - 1);
+ if (sz >= 0) {
+ char *p = meminfo_buf;
+ meminfo_buf[sz] = '\0';
+ /* Note that fields always appear in the match[] order */
for (i = 0; i < NUM_FIELDS; i++) {
- unsigned sz = (unsigned char)match[i][0];
- if (strncmp(linebuf, match[i] + 1, sz) == 0) {
+ char *found = strstr(p, match[i] + 1);
+ if (found) {
/* Cut "NNNN" out of " NNNN kb" */
- char *s = skip_whitespace(linebuf + sz);
- skip_non_whitespace(s)[0] = '\0';
- safe_strncpy(Z[i], s, sizeof(Z[i]));
- break;
+ char *s = skip_whitespace(found + match[i][0]);
+ p = skip_non_whitespace(s);
+ *p++ = '\0';
+ Z[i] = s;
}
}
}
- fclose(fp);
- snprintf(linebuf, sizeof(linebuf),
+ snprintf(line_buf, LINE_BUF_SIZE,
"Mem total:%s anon:%s map:%s free:%s",
Z[TOTAL], Z[ANON], Z[MAP], Z[MFREE]);
- printf(OPT_BATCH_MODE ? "%.*s\n" : "\033[H\033[J%.*s\n", scr_width, linebuf);
+ printf(OPT_BATCH_MODE ? "%.*s\n" : "\033[H\033[J%.*s\n", scr_width, line_buf);
- snprintf(linebuf, sizeof(linebuf),
+ snprintf(line_buf, LINE_BUF_SIZE,
" slab:%s buf:%s cache:%s dirty:%s write:%s",
Z[SLAB], Z[BUF], Z[CACHE], Z[DIRTY], Z[MWRITE]);
- printf("%.*s\n", scr_width, linebuf);
+ printf("%.*s\n", scr_width, line_buf);
- snprintf(linebuf, sizeof(linebuf),
+ snprintf(line_buf, LINE_BUF_SIZE,
"Swap total:%s free:%s", // TODO: % used?
Z[SWAPTOTAL], Z[SWAPFREE]);
- printf("%.*s\n", scr_width, linebuf);
+ printf("%.*s\n", scr_width, line_buf);
(*lines_rem_p) -= 3;
}