diff options
Diffstat (limited to 'procps/top.c')
-rw-r--r-- | procps/top.c | 149 |
1 files changed, 54 insertions, 95 deletions
diff --git a/procps/top.c b/procps/top.c index e4afafc4c..04dd82633 100644 --- a/procps/top.c +++ b/procps/top.c | |||
@@ -103,11 +103,11 @@ struct globals { | |||
103 | }; //FIX_ALIASING; - large code growth | 103 | }; //FIX_ALIASING; - large code growth |
104 | enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) }; | 104 | enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) }; |
105 | #define G (*(struct globals*)&bb_common_bufsiz1) | 105 | #define G (*(struct globals*)&bb_common_bufsiz1) |
106 | #define INIT_G() do { \ | 106 | struct BUG_bad_size { |
107 | struct G_sizecheck { \ | 107 | char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; |
108 | char G_sizecheck[sizeof(G) > COMMON_BUFSIZE ? -1 : 1]; \ | 108 | char BUG_line_buf_too_small[LINE_BUF_SIZE > 80 ? 1 : -1]; |
109 | }; \ | 109 | }; |
110 | } while (0) | 110 | #define INIT_G() do { } while (0) |
111 | #define top (G.top ) | 111 | #define top (G.top ) |
112 | #define ntop (G.ntop ) | 112 | #define ntop (G.ntop ) |
113 | #define sort_field (G.sort_field ) | 113 | #define sort_field (G.sort_field ) |
@@ -696,111 +696,70 @@ static int topmem_sort(char *a, char *b) | |||
696 | return inverted ? -n : n; | 696 | return inverted ? -n : n; |
697 | } | 697 | } |
698 | 698 | ||
699 | /* Cut "NNNN" out of " NNNN kb" */ | ||
700 | static char *grab_number(char *str, const char *match, unsigned sz) | ||
701 | { | ||
702 | if (strncmp(str, match, sz) == 0) { | ||
703 | str = skip_whitespace(str + sz); | ||
704 | (skip_non_whitespace(str))[0] = '\0'; | ||
705 | return xstrdup(str); | ||
706 | } | ||
707 | return NULL; | ||
708 | } | ||
709 | |||
710 | /* display header info (meminfo / loadavg) */ | 699 | /* display header info (meminfo / loadavg) */ |
711 | static void display_topmem_header(int scr_width, int *lines_rem_p) | 700 | static void display_topmem_header(int scr_width, int *lines_rem_p) |
712 | { | 701 | { |
713 | char linebuf[128]; | 702 | enum { |
703 | TOTAL = 0, MFREE, BUF, CACHE, | ||
704 | SWAPTOTAL, SWAPFREE, DIRTY, | ||
705 | MWRITE, ANON, MAP, SLAB, | ||
706 | NUM_FIELDS | ||
707 | }; | ||
708 | static const char match[NUM_FIELDS][12] = { | ||
709 | "\x09" "MemTotal:", // TOTAL | ||
710 | "\x08" "MemFree:", // MFREE | ||
711 | "\x08" "Buffers:", // BUF | ||
712 | "\x07" "Cached:", // CACHE | ||
713 | "\x0a" "SwapTotal:", // SWAPTOTAL | ||
714 | "\x09" "SwapFree:", // SWAPFREE | ||
715 | "\x06" "Dirty:", // DIRTY | ||
716 | "\x0a" "Writeback:", // MWRITE | ||
717 | "\x0a" "AnonPages:", // ANON | ||
718 | "\x07" "Mapped:", // MAP | ||
719 | "\x05" "Slab:", // SLAB | ||
720 | }; | ||
721 | char meminfo_buf[4 * 1024]; | ||
722 | const char *Z[NUM_FIELDS]; | ||
714 | unsigned i; | 723 | unsigned i; |
715 | FILE *fp; | 724 | int sz; |
716 | union { | 725 | |
717 | struct { | 726 | for (i = 0; i < NUM_FIELDS; i++) |
718 | /* 1 */ char *total; | 727 | Z[i] = "?"; |
719 | /* 2 */ char *mfree; | ||
720 | /* 3 */ char *buf; | ||
721 | /* 4 */ char *cache; | ||
722 | /* 5 */ char *swaptotal; | ||
723 | /* 6 */ char *swapfree; | ||
724 | /* 7 */ char *dirty; | ||
725 | /* 8 */ char *mwrite; | ||
726 | /* 9 */ char *anon; | ||
727 | /* 10 */ char *map; | ||
728 | /* 11 */ char *slab; | ||
729 | } u; | ||
730 | char *str[11]; | ||
731 | } Z; | ||
732 | #define total Z.u.total | ||
733 | #define mfree Z.u.mfree | ||
734 | #define buf Z.u.buf | ||
735 | #define cache Z.u.cache | ||
736 | #define swaptotal Z.u.swaptotal | ||
737 | #define swapfree Z.u.swapfree | ||
738 | #define dirty Z.u.dirty | ||
739 | #define mwrite Z.u.mwrite | ||
740 | #define anon Z.u.anon | ||
741 | #define map Z.u.map | ||
742 | #define slab Z.u.slab | ||
743 | #define str Z.str | ||
744 | |||
745 | memset(&Z, 0, sizeof(Z)); | ||
746 | 728 | ||
747 | /* read memory info */ | 729 | /* read memory info */ |
748 | fp = xfopen_for_read("meminfo"); | 730 | sz = open_read_close("meminfo", meminfo_buf, sizeof(meminfo_buf) - 1); |
749 | while (fgets(linebuf, sizeof(linebuf), fp)) { | 731 | if (sz >= 0) { |
750 | char *p; | 732 | char *p = meminfo_buf; |
751 | 733 | meminfo_buf[sz] = '\0'; | |
752 | #define SCAN(match, name) \ | 734 | /* Note that fields always appear in the match[] order */ |
753 | p = grab_number(linebuf, match, sizeof(match)-1); \ | 735 | for (i = 0; i < NUM_FIELDS; i++) { |
754 | if (p) { name = p; continue; } | 736 | char *found = strstr(p, match[i] + 1); |
755 | 737 | if (found) { | |
756 | SCAN("MemTotal:", total); | 738 | /* Cut "NNNN" out of " NNNN kb" */ |
757 | SCAN("MemFree:", mfree); | 739 | char *s = skip_whitespace(found + match[i][0]); |
758 | SCAN("Buffers:", buf); | 740 | p = skip_non_whitespace(s); |
759 | SCAN("Cached:", cache); | 741 | *p++ = '\0'; |
760 | SCAN("SwapTotal:", swaptotal); | 742 | Z[i] = s; |
761 | SCAN("SwapFree:", swapfree); | 743 | } |
762 | SCAN("Dirty:", dirty); | 744 | } |
763 | SCAN("Writeback:", mwrite); | ||
764 | SCAN("AnonPages:", anon); | ||
765 | SCAN("Mapped:", map); | ||
766 | SCAN("Slab:", slab); | ||
767 | #undef SCAN | ||
768 | } | 745 | } |
769 | fclose(fp); | ||
770 | 746 | ||
771 | #define S(s) (s ? s : "0") | 747 | snprintf(line_buf, LINE_BUF_SIZE, |
772 | snprintf(linebuf, sizeof(linebuf), | ||
773 | "Mem total:%s anon:%s map:%s free:%s", | 748 | "Mem total:%s anon:%s map:%s free:%s", |
774 | S(total), S(anon), S(map), S(mfree)); | 749 | Z[TOTAL], Z[ANON], Z[MAP], Z[MFREE]); |
775 | printf(OPT_BATCH_MODE ? "%.*s\n" : "\033[H\033[J%.*s\n", scr_width, linebuf); | 750 | printf(OPT_BATCH_MODE ? "%.*s\n" : "\033[H\033[J%.*s\n", scr_width, line_buf); |
776 | 751 | ||
777 | snprintf(linebuf, sizeof(linebuf), | 752 | snprintf(line_buf, LINE_BUF_SIZE, |
778 | " slab:%s buf:%s cache:%s dirty:%s write:%s", | 753 | " slab:%s buf:%s cache:%s dirty:%s write:%s", |
779 | S(slab), S(buf), S(cache), S(dirty), S(mwrite)); | 754 | Z[SLAB], Z[BUF], Z[CACHE], Z[DIRTY], Z[MWRITE]); |
780 | printf("%.*s\n", scr_width, linebuf); | 755 | printf("%.*s\n", scr_width, line_buf); |
781 | 756 | ||
782 | snprintf(linebuf, sizeof(linebuf), | 757 | snprintf(line_buf, LINE_BUF_SIZE, |
783 | "Swap total:%s free:%s", // TODO: % used? | 758 | "Swap total:%s free:%s", // TODO: % used? |
784 | S(swaptotal), S(swapfree)); | 759 | Z[SWAPTOTAL], Z[SWAPFREE]); |
785 | printf("%.*s\n", scr_width, linebuf); | 760 | printf("%.*s\n", scr_width, line_buf); |
786 | 761 | ||
787 | (*lines_rem_p) -= 3; | 762 | (*lines_rem_p) -= 3; |
788 | #undef S | ||
789 | |||
790 | for (i = 0; i < ARRAY_SIZE(str); i++) | ||
791 | free(str[i]); | ||
792 | #undef total | ||
793 | #undef free | ||
794 | #undef buf | ||
795 | #undef cache | ||
796 | #undef swaptotal | ||
797 | #undef swapfree | ||
798 | #undef dirty | ||
799 | #undef write | ||
800 | #undef anon | ||
801 | #undef map | ||
802 | #undef slab | ||
803 | #undef str | ||
804 | } | 763 | } |
805 | 764 | ||
806 | static void ulltoa6_and_space(unsigned long long ul, char buf[6]) | 765 | static void ulltoa6_and_space(unsigned long long ul, char buf[6]) |