aboutsummaryrefslogtreecommitdiff
path: root/procps/top.c
diff options
context:
space:
mode:
Diffstat (limited to 'procps/top.c')
-rw-r--r--procps/top.c149
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
104enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) }; 104enum { 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 { \ 106struct 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" */
700static 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) */
711static void display_topmem_header(int scr_width, int *lines_rem_p) 700static 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
806static void ulltoa6_and_space(unsigned long long ul, char buf[6]) 765static void ulltoa6_and_space(unsigned long long ul, char buf[6])