aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--procps/top.c60
1 files changed, 48 insertions, 12 deletions
diff --git a/procps/top.c b/procps/top.c
index cee1b52c1..9944598c2 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -311,14 +311,47 @@ static unsigned long display_generic(void)
311 char buf[80]; 311 char buf[80];
312 float avg1, avg2, avg3; 312 float avg1, avg2, avg3;
313 unsigned long total, used, mfree, shared, buffers, cached; 313 unsigned long total, used, mfree, shared, buffers, cached;
314 unsigned int needs_conversion = 1;
314 315
315 /* read memory info */ 316 /* read memory info */
316 fp = bb_xfopen("meminfo", "r"); 317 fp = bb_xfopen("meminfo", "r");
317 fgets(buf, sizeof(buf), fp); /* skip first line */
318 318
319 if (fscanf(fp, "Mem: %lu %lu %lu %lu %lu %lu", 319 /*
320 &total, &used, &mfree, &shared, &buffers, &cached) != 6) { 320 * Old kernels (such as 2.4.x) had a nice summary of memory info that
321 bb_error_msg_and_die("failed to read '%s'", "meminfo"); 321 * we could parse, however this is gone entirely in 2.6. Try parsing
322 * the old way first, and if that fails, parse each field manually.
323 *
324 * First, we read in the first line. Old kernels will have bogus
325 * strings we don't care about, whereas new kernels will start right
326 * out with MemTotal:
327 * -- PFM.
328 */
329 if (fscanf(fp, "MemTotal: %lu %s\n", &total, buf) != 2) {
330 fgets(buf, sizeof(buf), fp); /* skip first line */
331
332 fscanf(fp, "Mem: %lu %lu %lu %lu %lu %lu",
333 &total, &used, &mfree, &shared, &buffers, &cached);
334 } else {
335 /*
336 * Revert to manual parsing, which incidentally already has the
337 * sizes in kilobytes. This should be safe for both 2.4 and
338 * 2.6.
339 */
340 needs_conversion = 0;
341
342 fscanf(fp, "MemFree: %lu %s\n", &mfree, buf);
343
344 /*
345 * MemShared: is no longer present in 2.6. Report this as 0,
346 * to maintain consistent behavior with normal procps.
347 */
348 if (fscanf(fp, "MemShared: %lu %s\n", &shared, buf) != 2)
349 shared = 0;
350
351 fscanf(fp, "Buffers: %lu %s\n", &buffers, buf);
352 fscanf(fp, "Cached: %lu %s\n", &cached, buf);
353
354 used = total - mfree;
322 } 355 }
323 fclose(fp); 356 fclose(fp);
324 357
@@ -329,13 +362,16 @@ static unsigned long display_generic(void)
329 } 362 }
330 fclose(fp); 363 fclose(fp);
331 364
332 /* convert to kilobytes */ 365 if (needs_conversion) {
333 used /= 1024; 366 /* convert to kilobytes */
334 mfree /= 1024; 367 used /= 1024;
335 shared /= 1024; 368 mfree /= 1024;
336 buffers /= 1024; 369 shared /= 1024;
337 cached /= 1024; 370 buffers /= 1024;
338 371 cached /= 1024;
372 total /= 1024;
373 }
374
339 /* output memory info and load average */ 375 /* output memory info and load average */
340 /* clear screen & go to top */ 376 /* clear screen & go to top */
341 printf("\e[H\e[J" "Mem: " 377 printf("\e[H\e[J" "Mem: "
@@ -344,7 +380,7 @@ static unsigned long display_generic(void)
344 printf("Load average: %.2f, %.2f, %.2f " 380 printf("Load average: %.2f, %.2f, %.2f "
345 "(State: S=sleeping R=running, W=waiting)\n", 381 "(State: S=sleeping R=running, W=waiting)\n",
346 avg1, avg2, avg3); 382 avg1, avg2, avg3);
347 return total / 1024; 383 return total;
348} 384}
349 385
350 386