aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2025-08-06 00:42:05 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2025-08-06 00:42:05 +0200
commit8bde71eb1502a5cdf186769b47d470038f99bc95 (patch)
treee5097b7f948d1d6be6d5d47d5f2a36886cf3c242
parent1bd8d714ca1889558b26ab8f29a0f199ffdd2bd9 (diff)
downloadbusybox-w32-8bde71eb1502a5cdf186769b47d470038f99bc95.tar.gz
busybox-w32-8bde71eb1502a5cdf186769b47d470038f99bc95.tar.bz2
busybox-w32-8bde71eb1502a5cdf186769b47d470038f99bc95.zip
top: simplify command line reading
function old new delta cmdline_to_line_buf_and_print - 48 +48 read_cmdline 326 327 +1 display_topmem_process_list 523 505 -18 display_process_list 1186 1161 -25 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/2 up/down: 49/-43) Total: 6 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--libbb/procps.c21
-rw-r--r--procps/top.c23
2 files changed, 26 insertions, 18 deletions
diff --git a/libbb/procps.c b/libbb/procps.c
index 3256fafc5..fc31c075d 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -558,22 +558,29 @@ int FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm)
558 if (sz < 0) 558 if (sz < 0)
559 return sz; 559 return sz;
560 if (sz > 0) { 560 if (sz > 0) {
561 const char *base; 561 const char *program_basename;
562 int comm_len; 562 int comm_len;
563 563
564 buf[sz] = '\0'; 564 buf[sz] = '\0';
565 while (--sz >= 0 && buf[sz] == '\0') 565 while (--sz >= 0 && buf[sz] == '\0')
566 continue; 566 continue;
567 /* Prevent basename("process foo/bar") = "bar" */ 567
568 strchrnul(buf, ' ')[0] = '\0'; 568 /* Find "program" in "[-][/PATH/TO/]program" */
569 base = bb_basename(buf); /* before we replace argv0's NUL with space */ 569 strchrnul(buf, ' ')[0] = '\0'; /* prevent basename("program foo/bar") = "bar" */
570 program_basename = bb_basename(buf[0] == '-' ? buf + 1 : buf);
571 /* ^^^ note: must do it *before* replacing argv0's NUL with space */
572
573 /* Prevent stuff like this:
574 * echo 'sleep 999; exit' >`printf '\ec'`; sh ?c
575 * messing up top and ps output (or worse).
576 * This also replaces NULs with spaces, converting
577 * list of NUL-strings into one string.
578 */
570 while (sz >= 0) { 579 while (sz >= 0) {
571 if ((unsigned char)(buf[sz]) < ' ') 580 if ((unsigned char)(buf[sz]) < ' ')
572 buf[sz] = ' '; 581 buf[sz] = ' ';
573 sz--; 582 sz--;
574 } 583 }
575 if (base[0] == '-') /* "-sh" (login shell)? */
576 base++;
577 584
578 /* If comm differs from argv0, prepend "{comm} ". 585 /* If comm differs from argv0, prepend "{comm} ".
579 * It allows to see thread names set by prctl(PR_SET_NAME). 586 * It allows to see thread names set by prctl(PR_SET_NAME).
@@ -587,7 +594,7 @@ int FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm)
587 * I prefer to still treat argv0 "process foo bar" 594 * I prefer to still treat argv0 "process foo bar"
588 * as 'equal' to comm "process". 595 * as 'equal' to comm "process".
589 */ 596 */
590 if (strncmp(base, comm, comm_len) != 0) { 597 if (strncmp(program_basename, comm, comm_len) != 0) {
591 comm_len += 3; 598 comm_len += 3;
592 if (col > comm_len) 599 if (col > comm_len)
593 memmove(buf + comm_len, buf, col - comm_len); 600 memmove(buf + comm_len, buf, col - comm_len);
diff --git a/procps/top.c b/procps/top.c
index bff9f7c4f..96b3e2d4e 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -602,6 +602,15 @@ static void parse_meminfo(unsigned long meminfo[MI_MAX])
602 fclose(f); 602 fclose(f);
603} 603}
604 604
605static void cmdline_to_line_buf_and_print(unsigned offset, unsigned pid, const char *comm)
606{
607 int width = G.scr_width - offset;
608 if (width > 1) /* wider than to fit just the NUL? */
609 read_cmdline(G.line_buf + offset, width, pid, comm);
610//TODO: read_cmdline() sanitizes control chars, but not chars above 0x7e
611 print_line_buf();
612}
613
605static unsigned long display_header(void) 614static unsigned long display_header(void)
606{ 615{
607 char *buf; 616 char *buf;
@@ -789,9 +798,7 @@ static NOINLINE void display_process_list(void)
789 IF_FEATURE_TOP_SMP_PROCESS(, s->last_seen_on_cpu) 798 IF_FEATURE_TOP_SMP_PROCESS(, s->last_seen_on_cpu)
790 IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(, SHOW_STAT(pcpu)) 799 IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(, SHOW_STAT(pcpu))
791 ); 800 );
792 if ((int)(G.scr_width - col) > 1) 801 cmdline_to_line_buf_and_print(col, s->pid, s->comm);
793 read_cmdline(G.line_buf + col, G.scr_width - col, s->pid, s->comm);
794 print_line_buf();
795 /* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu, 802 /* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu,
796 cur_jif.busy - prev_jif.busy, cur_jif.total - prev_jif.total); */ 803 cur_jif.busy - prev_jif.busy, cur_jif.total - prev_jif.total); */
797 s++; 804 s++;
@@ -910,14 +917,12 @@ static void ulltoa4_and_space(unsigned long long ul, char buf[5])
910 917
911static NOINLINE void display_topmem_process_list(void) 918static NOINLINE void display_topmem_process_list(void)
912{ 919{
913#define HDR_STR " PID VSZ VSZRW RSS (SHR) DIRTY (SHR) STACK"
914#define MIN_WIDTH sizeof(HDR_STR)
915 const topmem_status_t *s = topmem + G_scroll_ofs; 920 const topmem_status_t *s = topmem + G_scroll_ofs;
916 char *cp, ch; 921 char *cp, ch;
917 922
918 display_topmem_header(); 923 display_topmem_header();
919 924
920 strcpy(G.line_buf, HDR_STR " COMMAND"); 925 strcpy(G.line_buf, " PID VSZ VSZRW RSS (SHR) DIRTY (SHR) STACK COMMAND");
921 /* Mark the ^FIELD^ we sort by */ 926 /* Mark the ^FIELD^ we sort by */
922 cp = &G.line_buf[5 + sort_field * 6]; 927 cp = &G.line_buf[5 + sort_field * 6];
923 ch = "^_"[inverted]; 928 ch = "^_"[inverted];
@@ -949,13 +954,9 @@ static NOINLINE void display_topmem_process_list(void)
949 ulltoa5_and_space(s->dirty_sh, &G.line_buf[6*6]); 954 ulltoa5_and_space(s->dirty_sh, &G.line_buf[6*6]);
950 ulltoa5_and_space(s->stack , &G.line_buf[7*6]); 955 ulltoa5_and_space(s->stack , &G.line_buf[7*6]);
951 G.line_buf[8*6] = '\0'; 956 G.line_buf[8*6] = '\0';
952 if ((int)(G.scr_width - MIN_WIDTH) > 1) 957 cmdline_to_line_buf_and_print(8*6, s->pid, s->comm);
953 read_cmdline(&G.line_buf[8*6], G.scr_width - MIN_WIDTH, s->pid, s->comm);
954 print_line_buf();
955 s++; 958 s++;
956 } 959 }
957#undef HDR_STR
958#undef MIN_WIDTH
959} 960}
960 961
961#endif /* end TOPMEM support */ 962#endif /* end TOPMEM support */