aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2025-08-06 00:05:44 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2025-08-06 00:05:44 +0200
commit1bd8d714ca1889558b26ab8f29a0f199ffdd2bd9 (patch)
treefe09a1dee81f5e44e008181014cc1cc442759cd2
parent23639388838448bb1968de70e84005904b316b93 (diff)
downloadbusybox-w32-1bd8d714ca1889558b26ab8f29a0f199ffdd2bd9.tar.gz
busybox-w32-1bd8d714ca1889558b26ab8f29a0f199ffdd2bd9.tar.bz2
busybox-w32-1bd8d714ca1889558b26ab8f29a0f199ffdd2bd9.zip
top: disentangle printing logic
function old new delta print_line_buf - 78 +78 print_line_bold - 50 +50 top_main 1043 1091 +48 handle_input 708 714 +6 do_stats 186 192 +6 .rodata 115543 115526 -17 display_topmem_process_list 748 523 -225 display_process_list 1432 1186 -246 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 3/3 up/down: 188/-488) Total: -300 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--procps/top.c180
1 files changed, 97 insertions, 83 deletions
diff --git a/procps/top.c b/procps/top.c
index 1f1c82b5a..bff9f7c4f 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -166,12 +166,14 @@ struct globals {
166 top_status_t *top; 166 top_status_t *top;
167 int ntop; 167 int ntop;
168 smallint inverted; 168 smallint inverted;
169 smallint not_first_line;
169#if ENABLE_FEATURE_TOPMEM 170#if ENABLE_FEATURE_TOPMEM
170 smallint sort_field; 171 smallint sort_field;
171#endif 172#endif
172#if ENABLE_FEATURE_TOP_SMP_CPU 173#if ENABLE_FEATURE_TOP_SMP_CPU
173 smallint smp_cpu_info; /* one/many cpu info lines? */ 174 smallint smp_cpu_info; /* one/many cpu info lines? */
174#endif 175#endif
176 int lines_remaining;
175 unsigned lines; /* screen height */ 177 unsigned lines; /* screen height */
176 unsigned scr_width; /* width, clamped <= LINE_BUF_SIZE-2 */ 178 unsigned scr_width; /* width, clamped <= LINE_BUF_SIZE-2 */
177#if ENABLE_FEATURE_TOP_INTERACTIVE 179#if ENABLE_FEATURE_TOP_INTERACTIVE
@@ -218,7 +220,6 @@ struct globals {
218#define cpu_prev_jif (G.cpu_prev_jif ) 220#define cpu_prev_jif (G.cpu_prev_jif )
219#define num_cpus (G.num_cpus ) 221#define num_cpus (G.num_cpus )
220#define total_pcpu (G.total_pcpu ) 222#define total_pcpu (G.total_pcpu )
221#define line_buf (G.line_buf )
222#define INIT_G() do { \ 223#define INIT_G() do { \
223 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 224 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
224 BUILD_BUG_ON(LINE_BUF_SIZE <= 80); \ 225 BUILD_BUG_ON(LINE_BUF_SIZE <= 80); \
@@ -289,9 +290,9 @@ static NOINLINE int read_cpu_jiffy(FILE *fp, jiffy_counts_t *p_jif)
289#endif 290#endif
290 int ret; 291 int ret;
291 292
292 if (!fgets(line_buf, LINE_BUF_SIZE, fp) || line_buf[0] != 'c' /* not "cpu" */) 293 if (!fgets(G.line_buf, LINE_BUF_SIZE, fp) || G.line_buf[0] != 'c' /* not "cpu" */)
293 return 0; 294 return 0;
294 ret = sscanf(line_buf, fmt, 295 ret = sscanf(G.line_buf, fmt,
295 &p_jif->usr, &p_jif->nic, &p_jif->sys, &p_jif->idle, 296 &p_jif->usr, &p_jif->nic, &p_jif->sys, &p_jif->idle,
296 &p_jif->iowait, &p_jif->irq, &p_jif->softirq, 297 &p_jif->iowait, &p_jif->irq, &p_jif->softirq,
297 &p_jif->steal); 298 &p_jif->steal);
@@ -413,6 +414,38 @@ static void do_stats(void)
413 414
414#endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */ 415#endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */
415 416
417static void print_line_buf(void)
418{
419 const char *fmt;
420
421 G.lines_remaining--;
422 fmt = OPT_BATCH_MODE ? "\n""%.*s" : "\n""%.*s"CLREOL;
423 if (!G.not_first_line) {
424 G.not_first_line = 1;
425 /* Go to top */
426 fmt = OPT_BATCH_MODE ? "%.*s" : HOME"%.*s"CLREOL;
427 }
428 printf(fmt, G.scr_width - 1, G.line_buf);
429}
430
431static void print_line_bold(void)
432{
433 G.lines_remaining--;
434//we never print first line in bold
435// if (!G.not_first_line) {
436// printf(OPT_BATCH_MODE ? "%.*s" : HOME"%.*s"CLREOL, G.scr_width - 1, G.line_buf);
437// G.not_first_line = 1;
438// } else {
439 printf(OPT_BATCH_MODE ? "\n""%.*s" : "\n"REVERSE"%.*s"NORMAL CLREOL, G.scr_width - 1, G.line_buf);
440// }
441}
442
443static void print_end(void)
444{
445 fputs_stdout(OPT_BATCH_MODE ? "\n" : CLREOS"\r");
446 G.not_first_line = 0; /* next print will be "first line" (will clear the screen) */
447}
448
416#if ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS && ENABLE_FEATURE_TOP_DECIMALS 449#if ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS && ENABLE_FEATURE_TOP_DECIMALS
417/* formats 7 char string (8 with terminating NUL) */ 450/* formats 7 char string (8 with terminating NUL) */
418static char *fmt_100percent_8(char pbuf[8], unsigned value, unsigned total) 451static char *fmt_100percent_8(char pbuf[8], unsigned value, unsigned total)
@@ -439,7 +472,7 @@ static char *fmt_100percent_8(char pbuf[8], unsigned value, unsigned total)
439#endif 472#endif
440 473
441#if ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS 474#if ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS
442static void display_cpus(char *scrbuf, int *lines_rem_p) 475static void display_cpus(void)
443{ 476{
444 /* 477 /*
445 * xxx% = (cur_jif.xxx - prev_jif.xxx) / (cur_jif.total - prev_jif.total) * 100% 478 * xxx% = (cur_jif.xxx - prev_jif.xxx) / (cur_jif.total - prev_jif.total) * 100%
@@ -475,8 +508,8 @@ static void display_cpus(char *scrbuf, int *lines_rem_p)
475# else 508# else
476 /* Loop thru CPU(s) */ 509 /* Loop thru CPU(s) */
477 n_cpu_lines = smp_cpu_info ? num_cpus : 1; 510 n_cpu_lines = smp_cpu_info ? num_cpus : 1;
478 if (n_cpu_lines > *lines_rem_p) 511 if (n_cpu_lines > G.lines_remaining)
479 n_cpu_lines = *lines_rem_p; 512 n_cpu_lines = G.lines_remaining;
480 513
481 for (i = 0; i < n_cpu_lines; i++) { 514 for (i = 0; i < n_cpu_lines; i++) {
482 p_jif = &cpu_jif[i]; 515 p_jif = &cpu_jif[i];
@@ -494,7 +527,7 @@ static void display_cpus(char *scrbuf, int *lines_rem_p)
494 CALC_STAT(softirq); 527 CALC_STAT(softirq);
495 /*CALC_STAT(steal);*/ 528 /*CALC_STAT(steal);*/
496 529
497 snprintf(scrbuf, G.scr_width, 530 sprintf(G.line_buf,
498 /* Barely fits in 79 chars when in "decimals" mode. */ 531 /* Barely fits in 79 chars when in "decimals" mode. */
499# if ENABLE_FEATURE_TOP_SMP_CPU 532# if ENABLE_FEATURE_TOP_SMP_CPU
500 "CPU%s:"FMT"usr"FMT"sys"FMT"nic"FMT"idle"FMT"io"FMT"irq"FMT"sirq", 533 "CPU%s:"FMT"usr"FMT"sys"FMT"nic"FMT"idle"FMT"io"FMT"irq"FMT"sirq",
@@ -507,16 +540,15 @@ static void display_cpus(char *scrbuf, int *lines_rem_p)
507 /*, SHOW_STAT(steal) - what is this 'steal' thing? */ 540 /*, SHOW_STAT(steal) - what is this 'steal' thing? */
508 /* I doubt anyone wants to know it */ 541 /* I doubt anyone wants to know it */
509 ); 542 );
510 printf(OPT_BATCH_MODE ? "%s\n" : "%s"CLREOL"\n", scrbuf); 543 print_line_buf();
511 } 544 }
512 } 545 }
513# undef SHOW_STAT 546# undef SHOW_STAT
514# undef CALC_STAT 547# undef CALC_STAT
515# undef FMT 548# undef FMT
516 *lines_rem_p -= i;
517} 549}
518#else /* !ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS */ 550#else /* !ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS */
519# define display_cpus(scrbuf, lines_rem) ((void)0) 551# define display_cpus() ((void)0)
520#endif 552#endif
521 553
522enum { 554enum {
@@ -570,51 +602,46 @@ static void parse_meminfo(unsigned long meminfo[MI_MAX])
570 fclose(f); 602 fclose(f);
571} 603}
572 604
573static unsigned long display_header(int *lines_rem_p) 605static unsigned long display_header(void)
574{ 606{
575 char scrbuf[100]; /* [80] was a bit too low on 8Gb ram box */
576 char *buf; 607 char *buf;
577 unsigned width;
578 unsigned long meminfo[MI_MAX]; 608 unsigned long meminfo[MI_MAX];
579 609
580 parse_meminfo(meminfo); 610 parse_meminfo(meminfo);
581 611
582 /* Output memory info */ 612 /* Output memory info */
583 width = (G.scr_width > sizeof(scrbuf)) ? sizeof(scrbuf) : G.scr_width; 613 sprintf(G.line_buf,
584 snprintf(scrbuf, width,
585 "Mem: %luK used, %luK free, %luK shrd, %luK buff, %luK cached", 614 "Mem: %luK used, %luK free, %luK shrd, %luK buff, %luK cached",
586 meminfo[MI_MEMTOTAL] - meminfo[MI_MEMFREE], 615 meminfo[MI_MEMTOTAL] - meminfo[MI_MEMFREE],
587 meminfo[MI_MEMFREE], 616 meminfo[MI_MEMFREE],
588 meminfo[MI_MEMSHARED] + meminfo[MI_SHMEM], 617 meminfo[MI_MEMSHARED] + meminfo[MI_SHMEM],
589 meminfo[MI_BUFFERS], 618 meminfo[MI_BUFFERS],
590 meminfo[MI_CACHED]); 619 meminfo[MI_CACHED]);
591 /* Go to top & clear to the end of screen */ 620 print_line_buf();
592 printf(OPT_BATCH_MODE ? "%s\n" : HOME"%s"CLREOL"\n", scrbuf);
593 (*lines_rem_p)--;
594 621
595 /* Display CPU time split as percentage of total time. 622 /* Display CPU time split as percentage of total time.
596 * This displays either a cumulative line or one line per CPU. 623 * This displays either a cumulative line or one line per CPU.
597 */ 624 */
598 display_cpus(scrbuf, lines_rem_p); 625 display_cpus();
599 626
600 /* Read load average as a string */ 627 /* Read load average as a string */
601 buf = stpcpy(scrbuf, "Load average: "); 628 buf = stpcpy(G.line_buf, "Load average: ");
602 open_read_close("loadavg", buf, sizeof(scrbuf) - sizeof("Load average: ")); 629 open_read_close("loadavg", buf, sizeof(G.line_buf) - sizeof("Load average: "));
630 G.line_buf[sizeof(G.line_buf) - 1] = '\0'; /* paranoia */
603 strchrnul(buf, '\n')[0] = '\0'; 631 strchrnul(buf, '\n')[0] = '\0';
604 printf(OPT_BATCH_MODE ? "%.*s\n" : "%.*s"CLREOL"\n", width - 1, scrbuf); 632 print_line_buf();
605 (*lines_rem_p)--;
606 633
607 return meminfo[MI_MEMTOTAL]; 634 return meminfo[MI_MEMTOTAL];
608} 635}
609 636
610static NOINLINE void display_process_list(int lines_rem) 637static NOINLINE void display_process_list(void)
611{ 638{
612 enum { 639 enum {
613 BITS_PER_INT = sizeof(int) * 8 640 BITS_PER_INT = sizeof(int) * 8
614 }; 641 };
615 642
616 top_status_t *s; 643 top_status_t *s;
617 unsigned long total_memory = display_header(&lines_rem); /* or use total_memsize? */ 644 unsigned long total_memory = display_header();
618 /* xxx_shift and xxx_scale variables allow us to replace 645 /* xxx_shift and xxx_scale variables allow us to replace
619 * expensive divides with multiply and shift */ 646 * expensive divides with multiply and shift */
620 unsigned pmem_shift, pmem_scale, pmem_half; 647 unsigned pmem_shift, pmem_scale, pmem_half;
@@ -626,7 +653,7 @@ static NOINLINE void display_process_list(int lines_rem)
626 653
627#if ENABLE_FEATURE_TOP_DECIMALS 654#if ENABLE_FEATURE_TOP_DECIMALS
628# define UPSCALE 1000 655# define UPSCALE 1000
629typedef struct { unsigned quot, rem; } bb_div_t; 656 typedef struct { unsigned quot, rem; } bb_div_t;
630/* Used to have "div_t name = div((val), 10)" here 657/* Used to have "div_t name = div((val), 10)" here
631 * (IOW: intended to use libc-compatible way to divide and use 658 * (IOW: intended to use libc-compatible way to divide and use
632 * both result and remainder, but musl does not inline div()...) 659 * both result and remainder, but musl does not inline div()...)
@@ -644,13 +671,11 @@ typedef struct { unsigned quot, rem; } bb_div_t;
644# define FMT "%4u%%" 671# define FMT "%4u%%"
645#endif 672#endif
646 673
647 /* what info of the processes is shown */ 674 strcpy(G.line_buf, " PID PPID USER STAT RSS %RSS"
648 printf(OPT_BATCH_MODE ? "%.*s" : REVERSE"%.*s"NORMAL CLREOL, G.scr_width - 1,
649 " PID PPID USER STAT RSS %RSS"
650 IF_FEATURE_TOP_SMP_PROCESS(" CPU") 675 IF_FEATURE_TOP_SMP_PROCESS(" CPU")
651 IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(" %CPU") 676 IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(" %CPU")
652 " COMMAND"); 677 " COMMAND");
653 lines_rem--; 678 print_line_bold();
654 679
655 /* %RSS = s->memsize / MemTotal * 100% 680 /* %RSS = s->memsize / MemTotal * 100%
656 * Calculate this with multiply and shift. Example: 681 * Calculate this with multiply and shift. Example:
@@ -702,12 +727,12 @@ typedef struct { unsigned quot, rem; } bb_div_t;
702 pcpu_half = (1U << pcpu_shift) / (ENABLE_FEATURE_TOP_DECIMALS ? 20 : 2); 727 pcpu_half = (1U << pcpu_shift) / (ENABLE_FEATURE_TOP_DECIMALS ? 20 : 2);
703 /* printf(" pmem_scale=%u pcpu_scale=%u ", pmem_scale, pcpu_scale); */ 728 /* printf(" pmem_scale=%u pcpu_scale=%u ", pmem_scale, pcpu_scale); */
704#endif 729#endif
705 if (lines_rem > ntop - G_scroll_ofs) 730 if (G.lines_remaining > ntop - G_scroll_ofs)
706 lines_rem = ntop - G_scroll_ofs; 731 G.lines_remaining = ntop - G_scroll_ofs;
707 732
708 /* Ok, all preliminary data is ready, go through the list */ 733 /* Ok, all preliminary data is ready, go through the list */
709 s = top + G_scroll_ofs; 734 s = top + G_scroll_ofs;
710 while (--lines_rem >= 0) { 735 while (G.lines_remaining > 0) {
711 int n; 736 int n;
712 char *ppu; 737 char *ppu;
713 char ppubuf[sizeof(int)*3 * 2 + 12]; 738 char ppubuf[sizeof(int)*3 * 2 + 12];
@@ -753,7 +778,7 @@ typedef struct { unsigned quot, rem; } bb_div_t;
753 ppu[6+6+8] = '\0'; /* truncate USER */ 778 ppu[6+6+8] = '\0'; /* truncate USER */
754 } 779 }
755 shortened: 780 shortened:
756 col = snprintf(line_buf, G.scr_width, 781 col = sprintf(G.line_buf,
757 "%s %s %.5s" FMT 782 "%s %s %.5s" FMT
758 IF_FEATURE_TOP_SMP_PROCESS(" %3d") 783 IF_FEATURE_TOP_SMP_PROCESS(" %3d")
759 IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(FMT) 784 IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(FMT)
@@ -765,14 +790,13 @@ typedef struct { unsigned quot, rem; } bb_div_t;
765 IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(, SHOW_STAT(pcpu)) 790 IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(, SHOW_STAT(pcpu))
766 ); 791 );
767 if ((int)(G.scr_width - col) > 1) 792 if ((int)(G.scr_width - col) > 1)
768 read_cmdline(line_buf + col, G.scr_width - col, s->pid, s->comm); 793 read_cmdline(G.line_buf + col, G.scr_width - col, s->pid, s->comm);
769 printf(OPT_BATCH_MODE ? "\n""%s" : "\n""%s"CLREOL, line_buf); 794 print_line_buf();
770 /* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu, 795 /* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu,
771 cur_jif.busy - prev_jif.busy, cur_jif.total - prev_jif.total); */ 796 cur_jif.busy - prev_jif.busy, cur_jif.total - prev_jif.total); */
772 s++; 797 s++;
773 } 798 }
774 /* printf(" %d", hist_iterations); */ 799 /* printf(" %d", hist_iterations); */
775 fputs_stdout(OPT_BATCH_MODE ? "\n" : CLREOS"\r");
776} 800}
777#undef UPSCALE 801#undef UPSCALE
778#undef SHOW_STAT 802#undef SHOW_STAT
@@ -844,36 +868,34 @@ static int topmem_sort(char *a, char *b)
844} 868}
845 869
846/* display header info (meminfo / loadavg) */ 870/* display header info (meminfo / loadavg) */
847static void display_topmem_header(int *lines_rem_p) 871static void display_topmem_header(void)
848{ 872{
849 unsigned long meminfo[MI_MAX]; 873 unsigned long meminfo[MI_MAX];
850 874
851 parse_meminfo(meminfo); 875 parse_meminfo(meminfo);
852 876
853 snprintf(line_buf, LINE_BUF_SIZE, 877 sprintf(G.line_buf,
854 "Mem total:%lu anon:%lu map:%lu free:%lu", 878 "Mem total:%lu anon:%lu map:%lu free:%lu",
855 meminfo[MI_MEMTOTAL], 879 meminfo[MI_MEMTOTAL],
856 meminfo[MI_ANONPAGES], 880 meminfo[MI_ANONPAGES],
857 meminfo[MI_MAPPED], 881 meminfo[MI_MAPPED],
858 meminfo[MI_MEMFREE]); 882 meminfo[MI_MEMFREE]);
859 printf(OPT_BATCH_MODE ? "%.*s\n" : HOME"%.*s"CLREOL"\n", G.scr_width - 1, line_buf); 883 print_line_buf();
860 884
861 snprintf(line_buf, LINE_BUF_SIZE, 885 sprintf(G.line_buf,
862 " slab:%lu buf:%lu cache:%lu dirty:%lu write:%lu", 886 " slab:%lu buf:%lu cache:%lu dirty:%lu write:%lu",
863 meminfo[MI_SLAB], 887 meminfo[MI_SLAB],
864 meminfo[MI_BUFFERS], 888 meminfo[MI_BUFFERS],
865 meminfo[MI_CACHED], 889 meminfo[MI_CACHED],
866 meminfo[MI_DIRTY], 890 meminfo[MI_DIRTY],
867 meminfo[MI_WRITEBACK]); 891 meminfo[MI_WRITEBACK]);
868 printf(OPT_BATCH_MODE ? "%.*s\n" : "%.*s"CLREOL"\n", G.scr_width - 1, line_buf); 892 print_line_buf();
869 893
870 snprintf(line_buf, LINE_BUF_SIZE, 894 sprintf(G.line_buf,
871 "Swap total:%lu free:%lu", // TODO: % used? 895 "Swap total:%lu free:%lu", // TODO: % used?
872 meminfo[MI_SWAPTOTAL], 896 meminfo[MI_SWAPTOTAL],
873 meminfo[MI_SWAPFREE]); 897 meminfo[MI_SWAPFREE]);
874 printf(OPT_BATCH_MODE ? "%.*s\n" : "%.*s"CLREOL"\n", G.scr_width - 1, line_buf); 898 print_line_buf();
875
876 (*lines_rem_p) -= 3;
877} 899}
878 900
879/* see http://en.wikipedia.org/wiki/Tera */ 901/* see http://en.wikipedia.org/wiki/Tera */
@@ -886,67 +908,57 @@ static void ulltoa4_and_space(unsigned long long ul, char buf[5])
886 smart_ulltoa4(ul, buf, " mgtpezy")[0] = ' '; 908 smart_ulltoa4(ul, buf, " mgtpezy")[0] = ' ';
887} 909}
888 910
889static NOINLINE void display_topmem_process_list(int lines_rem) 911static NOINLINE void display_topmem_process_list(void)
890{ 912{
891#define HDR_STR " PID VSZ VSZRW RSS (SHR) DIRTY (SHR) STACK" 913#define HDR_STR " PID VSZ VSZRW RSS (SHR) DIRTY (SHR) STACK"
892#define MIN_WIDTH sizeof(HDR_STR) 914#define MIN_WIDTH sizeof(HDR_STR)
893 const topmem_status_t *s = topmem + G_scroll_ofs; 915 const topmem_status_t *s = topmem + G_scroll_ofs;
894 char *cp, ch; 916 char *cp, ch;
895 917
896 display_topmem_header(&lines_rem); 918 display_topmem_header();
897 919
898 strcpy(line_buf, HDR_STR " COMMAND"); 920 strcpy(G.line_buf, HDR_STR " COMMAND");
899 /* Mark the ^FIELD^ we sort by */ 921 /* Mark the ^FIELD^ we sort by */
900 cp = &line_buf[5 + sort_field * 6]; 922 cp = &G.line_buf[5 + sort_field * 6];
901 ch = "^_"[inverted]; 923 ch = "^_"[inverted];
902 cp[6] = ch; 924 cp[6] = ch;
903 do *cp++ = ch; while (*cp == ' '); 925 do *cp++ = ch; while (*cp == ' ');
926 print_line_bold();
904 927
905 printf(OPT_BATCH_MODE ? "%.*s" : REVERSE"%.*s"NORMAL CLREOL, G.scr_width - 1, line_buf); 928 if (G.lines_remaining > ntop - G_scroll_ofs)
906 lines_rem--; 929 G.lines_remaining = ntop - G_scroll_ofs;
907 930 while (G.lines_remaining > 0) {
908 if (lines_rem > ntop - G_scroll_ofs)
909 lines_rem = ntop - G_scroll_ofs;
910 while (--lines_rem >= 0) {
911 /* PID VSZ VSZRW RSS (SHR) DIRTY (SHR) COMMAND */ 931 /* PID VSZ VSZRW RSS (SHR) DIRTY (SHR) COMMAND */
912 int n = sprintf(line_buf, "%5u ", s->pid); 932 int n = sprintf(G.line_buf, "%5u ", s->pid);
913 if (n > 7) { 933 if (n > 7) {
914 /* PID is 7 chars long (up to 4194304) */ 934 /* PID is 7 chars long (up to 4194304) */
915 ulltoa4_and_space(s->vsz , &line_buf[8]); 935 ulltoa4_and_space(s->vsz , &G.line_buf[8]);
916 ulltoa4_and_space(s->vszrw, &line_buf[8+5]); 936 ulltoa4_and_space(s->vszrw, &G.line_buf[8+5]);
917 /* the next field (RSS) starts at 8+10 = 3*6 */ 937 /* the next field (RSS) starts at 8+10 = 3*6 */
918 } else { 938 } else {
919 if (n == 7) /* PID is 6 chars long */ 939 if (n == 7) /* PID is 6 chars long */
920 ulltoa4_and_space(s->vsz, &line_buf[7]); 940 ulltoa4_and_space(s->vsz, &G.line_buf[7]);
921 /* the next field (VSZRW) starts at 7+5 = 2*6 */ 941 /* the next field (VSZRW) starts at 7+5 = 2*6 */
922 else /* PID is 5 chars or less */ 942 else /* PID is 5 chars or less */
923 ulltoa5_and_space(s->vsz, &line_buf[6]); 943 ulltoa5_and_space(s->vsz, &G.line_buf[6]);
924 ulltoa5_and_space(s->vszrw, &line_buf[2*6]); 944 ulltoa5_and_space(s->vszrw, &G.line_buf[2*6]);
925 } 945 }
926 ulltoa5_and_space(s->rss , &line_buf[3*6]); 946 ulltoa5_and_space(s->rss , &G.line_buf[3*6]);
927 ulltoa5_and_space(s->rss_sh , &line_buf[4*6]); 947 ulltoa5_and_space(s->rss_sh , &G.line_buf[4*6]);
928 ulltoa5_and_space(s->dirty , &line_buf[5*6]); 948 ulltoa5_and_space(s->dirty , &G.line_buf[5*6]);
929 ulltoa5_and_space(s->dirty_sh, &line_buf[6*6]); 949 ulltoa5_and_space(s->dirty_sh, &G.line_buf[6*6]);
930 ulltoa5_and_space(s->stack , &line_buf[7*6]); 950 ulltoa5_and_space(s->stack , &G.line_buf[7*6]);
931 line_buf[8*6] = '\0'; 951 G.line_buf[8*6] = '\0';
932 if ((int)(G.scr_width - MIN_WIDTH) > 1) 952 if ((int)(G.scr_width - MIN_WIDTH) > 1)
933 read_cmdline(&line_buf[8*6], G.scr_width - MIN_WIDTH, s->pid, s->comm); 953 read_cmdline(&G.line_buf[8*6], G.scr_width - MIN_WIDTH, s->pid, s->comm);
934 printf(OPT_BATCH_MODE ? "\n""%.*s" : "\n""%.*s"CLREOL, G.scr_width, line_buf); 954 print_line_buf();
935 s++; 955 s++;
936 } 956 }
937 fputs_stdout(OPT_BATCH_MODE ? "\n" : CLREOS"\r");
938#undef HDR_STR 957#undef HDR_STR
939#undef MIN_WIDTH 958#undef MIN_WIDTH
940} 959}
941 960
942#else 961#endif /* end TOPMEM support */
943//void display_topmem_process_list(int lines_rem);
944//int topmem_sort(char *a, char *b);
945#endif /* TOPMEM */
946
947/*
948 * end TOPMEM support
949 */
950 962
951enum { 963enum {
952 TOP_MASK = 0 964 TOP_MASK = 0
@@ -1228,7 +1240,6 @@ int top_main(int argc UNUSED_PARAM, char **argv)
1228 } 1240 }
1229#endif 1241#endif
1230 1242
1231 /* change to /proc */
1232 xchdir("/proc"); 1243 xchdir("/proc");
1233 1244
1234#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 1245#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
@@ -1340,14 +1351,16 @@ int top_main(int argc UNUSED_PARAM, char **argv)
1340 } 1351 }
1341#endif 1352#endif
1342 IF_FEATURE_TOP_INTERACTIVE(redraw:) 1353 IF_FEATURE_TOP_INTERACTIVE(redraw:)
1354 G.lines_remaining = G.lines;
1343 IF_FEATURE_TOPMEM(if (scan_mask != TOPMEM_MASK)) { 1355 IF_FEATURE_TOPMEM(if (scan_mask != TOPMEM_MASK)) {
1344 display_process_list(G.lines); 1356 display_process_list();
1345 } 1357 }
1346#if ENABLE_FEATURE_TOPMEM 1358#if ENABLE_FEATURE_TOPMEM
1347 else { /* TOPMEM */ 1359 else { /* TOPMEM */
1348 display_topmem_process_list(G.lines); 1360 display_topmem_process_list();
1349 } 1361 }
1350#endif 1362#endif
1363 print_end();
1351 fflush_all(); 1364 fflush_all();
1352 if (iterations >= 0 && !--iterations) 1365 if (iterations >= 0 && !--iterations)
1353 break; 1366 break;
@@ -1369,7 +1382,8 @@ int top_main(int argc UNUSED_PARAM, char **argv)
1369#endif 1382#endif
1370 } /* end of "while (not Q)" */ 1383 } /* end of "while (not Q)" */
1371 1384
1372 bb_putchar('\n'); 1385 if (!OPT_BATCH_MODE)
1386 bb_putchar('\n');
1373#if ENABLE_FEATURE_TOP_INTERACTIVE 1387#if ENABLE_FEATURE_TOP_INTERACTIVE
1374 reset_term(); 1388 reset_term();
1375#endif 1389#endif