diff options
author | Ron Yorston <rmy@pobox.com> | 2014-10-06 12:50:22 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2014-10-06 12:50:22 +0100 |
commit | b04d11dcbadda2620743a1dd923938f2f3043a38 (patch) | |
tree | 971afe425a81304b79e44122e220c7a69efe2616 /procps | |
parent | 124bbf02948b7ac0babb4ead04acd1559db182d3 (diff) | |
parent | 760d035699c4a878f9109544c1d35ea0d5f6b76c (diff) | |
download | busybox-w32-b04d11dcbadda2620743a1dd923938f2f3043a38.tar.gz busybox-w32-b04d11dcbadda2620743a1dd923938f2f3043a38.tar.bz2 busybox-w32-b04d11dcbadda2620743a1dd923938f2f3043a38.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'procps')
-rw-r--r-- | procps/top.c | 197 |
1 files changed, 86 insertions, 111 deletions
diff --git a/procps/top.c b/procps/top.c index 530f45fa1..3d67c3cfd 100644 --- a/procps/top.c +++ b/procps/top.c | |||
@@ -499,85 +499,93 @@ static void display_cpus(int scr_width, char *scrbuf, int *lines_rem_p) | |||
499 | # define display_cpus(scr_width, scrbuf, lines_rem) ((void)0) | 499 | # define display_cpus(scr_width, scrbuf, lines_rem) ((void)0) |
500 | #endif | 500 | #endif |
501 | 501 | ||
502 | static unsigned long display_header(int scr_width, int *lines_rem_p) | 502 | enum { |
503 | { | 503 | MI_MEMTOTAL, |
504 | FILE *fp; | 504 | MI_MEMFREE, |
505 | char buf[80]; | 505 | MI_MEMSHARED, |
506 | char scrbuf[80]; | 506 | MI_SHMEM, |
507 | unsigned long total, used, mfree, shared, buffers, cached; | 507 | MI_BUFFERS, |
508 | 508 | MI_CACHED, | |
509 | /* read memory info */ | 509 | MI_SWAPTOTAL, |
510 | fp = xfopen_for_read("meminfo"); | 510 | MI_SWAPFREE, |
511 | MI_DIRTY, | ||
512 | MI_WRITEBACK, | ||
513 | MI_ANONPAGES, | ||
514 | MI_MAPPED, | ||
515 | MI_SLAB, | ||
516 | MI_MAX | ||
517 | }; | ||
511 | 518 | ||
512 | /* | 519 | static void parse_meminfo(unsigned long meminfo[MI_MAX]) |
513 | * Old kernels (such as 2.4.x) had a nice summary of memory info that | 520 | { |
514 | * we could parse, however this is gone entirely in 2.6. Try parsing | 521 | static const char fields[] = |
515 | * the old way first, and if that fails, parse each field manually. | 522 | "MemTotal\0" |
516 | * | 523 | "MemFree\0" |
517 | * First, we read in the first line. Old kernels will have bogus | 524 | "MemShared\0" |
518 | * strings we don't care about, whereas new kernels will start right | 525 | "Shmem\0" |
519 | * out with MemTotal: | 526 | "Buffers\0" |
520 | * -- PFM. | 527 | "Cached\0" |
521 | */ | 528 | "SwapTotal\0" |
522 | if (fscanf(fp, "MemTotal: %lu %s\n", &total, buf) != 2) { | 529 | "SwapFree\0" |
523 | fgets(buf, sizeof(buf), fp); /* skip first line */ | 530 | "Dirty\0" |
524 | 531 | "Writeback\0" | |
525 | fscanf(fp, "Mem: %lu %lu %lu %lu %lu %lu", | 532 | "AnonPages\0" |
526 | &total, &used, &mfree, &shared, &buffers, &cached); | 533 | "Mapped\0" |
527 | /* convert to kilobytes */ | 534 | "Slab\0"; |
528 | used /= 1024; | 535 | char buf[60]; /* actual lines we expect are ~30 chars or less */ |
529 | mfree /= 1024; | 536 | FILE *f; |
530 | shared /= 1024; | 537 | int i; |
531 | buffers /= 1024; | ||
532 | cached /= 1024; | ||
533 | total /= 1024; | ||
534 | } else { | ||
535 | /* | ||
536 | * Revert to manual parsing, which incidentally already has the | ||
537 | * sizes in kilobytes. This should be safe for both 2.4 and | ||
538 | * 2.6. | ||
539 | */ | ||
540 | fscanf(fp, "MemFree: %lu %s\n", &mfree, buf); | ||
541 | 538 | ||
542 | /* | 539 | memset(meminfo, 0, sizeof(meminfo[0]) * MI_MAX); |
543 | * MemShared: is no longer present in 2.6. Report this as 0, | 540 | f = xfopen_for_read("meminfo"); |
544 | * to maintain consistent behavior with normal procps. | 541 | while (fgets(buf, sizeof(buf), f) != NULL) { |
545 | */ | 542 | char *c = strchr(buf, ':'); |
546 | if (fscanf(fp, "MemShared: %lu %s\n", &shared, buf) != 2) | 543 | if (!c) |
547 | shared = 0; | 544 | continue; |
545 | *c = '\0'; | ||
546 | i = index_in_strings(fields, buf); | ||
547 | if (i >= 0) | ||
548 | meminfo[i] = strtoul(c+1, NULL, 10); | ||
549 | } | ||
550 | fclose(f); | ||
551 | } | ||
548 | 552 | ||
549 | fscanf(fp, "Buffers: %lu %s\n", &buffers, buf); | 553 | static unsigned long display_header(int scr_width, int *lines_rem_p) |
550 | fscanf(fp, "Cached: %lu %s\n", &cached, buf); | 554 | { |
555 | char scrbuf[100]; /* [80] was a bit too low on 8Gb ram box */ | ||
556 | char *buf; | ||
557 | unsigned long meminfo[MI_MAX]; | ||
551 | 558 | ||
552 | used = total - mfree; | 559 | parse_meminfo(meminfo); |
553 | } | ||
554 | fclose(fp); | ||
555 | 560 | ||
556 | /* output memory info */ | 561 | /* Output memory info */ |
557 | if (scr_width > (int)sizeof(scrbuf)) | 562 | if (scr_width > (int)sizeof(scrbuf)) |
558 | scr_width = sizeof(scrbuf); | 563 | scr_width = sizeof(scrbuf); |
559 | snprintf(scrbuf, scr_width, | 564 | snprintf(scrbuf, scr_width, |
560 | "Mem: %luK used, %luK free, %luK shrd, %luK buff, %luK cached", | 565 | "Mem: %luK used, %luK free, %luK shrd, %luK buff, %luK cached", |
561 | used, mfree, shared, buffers, cached); | 566 | meminfo[MI_MEMTOTAL] - meminfo[MI_MEMFREE], |
562 | /* go to top & clear to the end of screen */ | 567 | meminfo[MI_MEMFREE], |
568 | meminfo[MI_MEMSHARED] + meminfo[MI_SHMEM], | ||
569 | meminfo[MI_BUFFERS], | ||
570 | meminfo[MI_CACHED]); | ||
571 | /* Go to top & clear to the end of screen */ | ||
563 | printf(OPT_BATCH_MODE ? "%s\n" : "\033[H\033[J%s\n", scrbuf); | 572 | printf(OPT_BATCH_MODE ? "%s\n" : "\033[H\033[J%s\n", scrbuf); |
564 | (*lines_rem_p)--; | 573 | (*lines_rem_p)--; |
565 | 574 | ||
566 | /* Display CPU time split as percentage of total time | 575 | /* Display CPU time split as percentage of total time. |
567 | * This displays either a cumulative line or one line per CPU | 576 | * This displays either a cumulative line or one line per CPU. |
568 | */ | 577 | */ |
569 | display_cpus(scr_width, scrbuf, lines_rem_p); | 578 | display_cpus(scr_width, scrbuf, lines_rem_p); |
570 | 579 | ||
571 | /* read load average as a string */ | 580 | /* Read load average as a string */ |
572 | buf[0] = '\0'; | 581 | buf = stpcpy(scrbuf, "Load average: "); |
573 | open_read_close("loadavg", buf, sizeof(buf) - 1); | 582 | open_read_close("loadavg", buf, sizeof(scrbuf) - sizeof("Load average: ")); |
574 | buf[sizeof(buf) - 1] = '\n'; | 583 | scrbuf[scr_width - 1] = '\0'; |
575 | *strchr(buf, '\n') = '\0'; | 584 | strchrnul(buf, '\n')[0] = '\0'; |
576 | snprintf(scrbuf, scr_width, "Load average: %s", buf); | ||
577 | puts(scrbuf); | 585 | puts(scrbuf); |
578 | (*lines_rem_p)--; | 586 | (*lines_rem_p)--; |
579 | 587 | ||
580 | return total; | 588 | return meminfo[MI_MEMTOTAL]; |
581 | } | 589 | } |
582 | 590 | ||
583 | static NOINLINE void display_process_list(int lines_rem, int scr_width) | 591 | static NOINLINE void display_process_list(int lines_rem, int scr_width) |
@@ -781,64 +789,31 @@ static int topmem_sort(char *a, char *b) | |||
781 | /* display header info (meminfo / loadavg) */ | 789 | /* display header info (meminfo / loadavg) */ |
782 | static void display_topmem_header(int scr_width, int *lines_rem_p) | 790 | static void display_topmem_header(int scr_width, int *lines_rem_p) |
783 | { | 791 | { |
784 | enum { | 792 | unsigned long meminfo[MI_MAX]; |
785 | TOTAL = 0, MFREE, BUF, CACHE, | 793 | |
786 | SWAPTOTAL, SWAPFREE, DIRTY, | 794 | parse_meminfo(meminfo); |
787 | MWRITE, ANON, MAP, SLAB, | ||
788 | NUM_FIELDS | ||
789 | }; | ||
790 | static const char match[NUM_FIELDS][12] = { | ||
791 | "\x09" "MemTotal:", // TOTAL | ||
792 | "\x08" "MemFree:", // MFREE | ||
793 | "\x08" "Buffers:", // BUF | ||
794 | "\x07" "Cached:", // CACHE | ||
795 | "\x0a" "SwapTotal:", // SWAPTOTAL | ||
796 | "\x09" "SwapFree:", // SWAPFREE | ||
797 | "\x06" "Dirty:", // DIRTY | ||
798 | "\x0a" "Writeback:", // MWRITE | ||
799 | "\x0a" "AnonPages:", // ANON | ||
800 | "\x07" "Mapped:", // MAP | ||
801 | "\x05" "Slab:", // SLAB | ||
802 | }; | ||
803 | char meminfo_buf[4 * 1024]; | ||
804 | const char *Z[NUM_FIELDS]; | ||
805 | unsigned i; | ||
806 | int sz; | ||
807 | |||
808 | for (i = 0; i < NUM_FIELDS; i++) | ||
809 | Z[i] = "?"; | ||
810 | |||
811 | /* read memory info */ | ||
812 | sz = open_read_close("meminfo", meminfo_buf, sizeof(meminfo_buf) - 1); | ||
813 | if (sz >= 0) { | ||
814 | char *p = meminfo_buf; | ||
815 | meminfo_buf[sz] = '\0'; | ||
816 | /* Note that fields always appear in the match[] order */ | ||
817 | for (i = 0; i < NUM_FIELDS; i++) { | ||
818 | char *found = strstr(p, match[i] + 1); | ||
819 | if (found) { | ||
820 | /* Cut "NNNN" out of " NNNN kb" */ | ||
821 | char *s = skip_whitespace(found + match[i][0]); | ||
822 | p = skip_non_whitespace(s); | ||
823 | *p++ = '\0'; | ||
824 | Z[i] = s; | ||
825 | } | ||
826 | } | ||
827 | } | ||
828 | 795 | ||
829 | snprintf(line_buf, LINE_BUF_SIZE, | 796 | snprintf(line_buf, LINE_BUF_SIZE, |
830 | "Mem total:%s anon:%s map:%s free:%s", | 797 | "Mem total:%lu anon:%lu map:%lu free:%lu", |
831 | Z[TOTAL], Z[ANON], Z[MAP], Z[MFREE]); | 798 | meminfo[MI_MEMTOTAL], |
799 | meminfo[MI_ANONPAGES], | ||
800 | meminfo[MI_MAPPED], | ||
801 | meminfo[MI_MEMFREE]); | ||
832 | printf(OPT_BATCH_MODE ? "%.*s\n" : "\033[H\033[J%.*s\n", scr_width, line_buf); | 802 | printf(OPT_BATCH_MODE ? "%.*s\n" : "\033[H\033[J%.*s\n", scr_width, line_buf); |
833 | 803 | ||
834 | snprintf(line_buf, LINE_BUF_SIZE, | 804 | snprintf(line_buf, LINE_BUF_SIZE, |
835 | " slab:%s buf:%s cache:%s dirty:%s write:%s", | 805 | " slab:%lu buf:%lu cache:%lu dirty:%lu write:%lu", |
836 | Z[SLAB], Z[BUF], Z[CACHE], Z[DIRTY], Z[MWRITE]); | 806 | meminfo[MI_SLAB], |
807 | meminfo[MI_BUFFERS], | ||
808 | meminfo[MI_CACHED], | ||
809 | meminfo[MI_DIRTY], | ||
810 | meminfo[MI_WRITEBACK]); | ||
837 | printf("%.*s\n", scr_width, line_buf); | 811 | printf("%.*s\n", scr_width, line_buf); |
838 | 812 | ||
839 | snprintf(line_buf, LINE_BUF_SIZE, | 813 | snprintf(line_buf, LINE_BUF_SIZE, |
840 | "Swap total:%s free:%s", // TODO: % used? | 814 | "Swap total:%lu free:%lu", // TODO: % used? |
841 | Z[SWAPTOTAL], Z[SWAPFREE]); | 815 | meminfo[MI_SWAPTOTAL], |
816 | meminfo[MI_SWAPFREE]); | ||
842 | printf("%.*s\n", scr_width, line_buf); | 817 | printf("%.*s\n", scr_width, line_buf); |
843 | 818 | ||
844 | (*lines_rem_p) -= 3; | 819 | (*lines_rem_p) -= 3; |