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 | ||
