diff options
-rw-r--r-- | procps/top.c | 60 |
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 | ||