[PATCH] top: fix parsing of /proc/meminfo
Timo Teräs
timo.teras at iki.fi
Fri Jul 18 19:07:06 UTC 2014
and do it in smaller code:
function old new delta
.rodata 120254 120205 -49
display_process_list 1705 1563 -142
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-191) Total: -191 bytes
Signed-off-by: Timo Teräs <timo.teras at iki.fi>
---
procps/top.c | 80 +++++++++++++++++++++++++++++++++---------------------------
1 file changed, 44 insertions(+), 36 deletions(-)
diff --git a/procps/top.c b/procps/top.c
index 530f45f..e60dab6 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -501,10 +501,27 @@ static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p)
static unsigned long display_header(int scr_width, int *lines_rem_p)
{
+ static const char *fields =
+ "MemTotal\0"
+ "MemFree\0"
+ "Shmem\0"
+ "Buffers\0"
+ "Cached\0"
+ "Mem\0";
+ enum {
+ Hdr_Total,
+ Hdr_Free,
+ Hdr_Shared,
+ Hdr_Buffers,
+ Hdr_Cached,
+ Hdr_Legacy,
+ Hdr_Used,
+ Hdr_Max
+ };
FILE *fp;
- char buf[80];
- char scrbuf[80];
- unsigned long total, used, mfree, shared, buffers, cached;
+ char scrbuf[80], buf[80], *c;
+ unsigned long vals[Hdr_Max];
+ int i;
/* read memory info */
fp = xfopen_for_read("meminfo");
@@ -519,38 +536,28 @@ static unsigned long display_header(int scr_width, int *lines_rem_p)
* out with MemTotal:
* -- PFM.
*/
- if (fscanf(fp, "MemTotal: %lu %s\n", &total, buf) != 2) {
- fgets(buf, sizeof(buf), fp); /* skip first line */
-
- fscanf(fp, "Mem: %lu %lu %lu %lu %lu %lu",
- &total, &used, &mfree, &shared, &buffers, &cached);
- /* convert to kilobytes */
- used /= 1024;
- mfree /= 1024;
- shared /= 1024;
- buffers /= 1024;
- cached /= 1024;
- total /= 1024;
- } else {
- /*
- * Revert to manual parsing, which incidentally already has the
- * sizes in kilobytes. This should be safe for both 2.4 and
- * 2.6.
- */
- fscanf(fp, "MemFree: %lu %s\n", &mfree, buf);
-
- /*
- * MemShared: is no longer present in 2.6. Report this as 0,
- * to maintain consistent behavior with normal procps.
- */
- if (fscanf(fp, "MemShared: %lu %s\n", &shared, buf) != 2)
- shared = 0;
-
- fscanf(fp, "Buffers: %lu %s\n", &buffers, buf);
- fscanf(fp, "Cached: %lu %s\n", &cached, buf);
-
- used = total - mfree;
+ memset(vals, 0, sizeof(vals));
+ while (fgets(buf, sizeof(buf), fp)) {
+ c = strchr(buf, ':');
+ if (!c) continue;
+ *c = 0;
+
+ i = index_in_strings(fields, buf);
+ if (i < 0) continue;
+ if (i == Hdr_Legacy) {
+ sscanf(c+1, "%lu %lu %lu %lu %lu %lu",
+ &vals[Hdr_Total], &vals[Hdr_Used],
+ &vals[Hdr_Free], &vals[Hdr_Shared],
+ &vals[Hdr_Buffers], &vals[Hdr_Cached]);
+ /* convert to kilobytes */
+ for (i = 0; i < Hdr_Max; i++)
+ vals[i] /= 1024;
+ goto got_meminfo;
+ }
+ vals[i] = strtoul(c+1, NULL, 0);
}
+ vals[Hdr_Used] = vals[Hdr_Total] - vals[Hdr_Free];
+got_meminfo:
fclose(fp);
/* output memory info */
@@ -558,7 +565,8 @@ static unsigned long display_header(int scr_width, int *lines_rem_p)
scr_width = sizeof(scrbuf);
snprintf(scrbuf, scr_width,
"Mem: %luK used, %luK free, %luK shrd, %luK buff, %luK cached",
- used, mfree, shared, buffers, cached);
+ vals[Hdr_Used], vals[Hdr_Free], vals[Hdr_Shared],
+ vals[Hdr_Buffers], vals[Hdr_Cached]);
/* go to top & clear to the end of screen */
printf(OPT_BATCH_MODE ? "%s\n" : "\033[H\033[J%s\n", scrbuf);
(*lines_rem_p)--;
@@ -577,7 +585,7 @@ static unsigned long display_header(int scr_width, int *lines_rem_p)
puts(scrbuf);
(*lines_rem_p)--;
- return total;
+ return vals[Hdr_Total];
}
static NOINLINE void display_process_list(int lines_rem, int scr_width)
--
2.0.2
More information about the busybox
mailing list