top: simplify command line reading
No binary (build failed)
—
(log yok)
| @@ -558,22 +558,29 @@ int FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) | |
| if (sz < 0) | |
| return sz; | |
| if (sz > 0) { | |
| - | const char *base; |
| + | const char *program_basename; |
| int comm_len; | |
| buf[sz] = '\0'; | |
| while (--sz >= 0 && buf[sz] == '\0') | |
| continue; | |
| - | /* Prevent basename("process foo/bar") = "bar" */ |
| - | strchrnul(buf, ' ')[0] = '\0'; |
| - | base = bb_basename(buf); /* before we replace argv0's NUL with space */ |
| + | |
| + | /* Find "program" in "[-][/PATH/TO/]program" */ |
| + | strchrnul(buf, ' ')[0] = '\0'; /* prevent basename("program foo/bar") = "bar" */ |
| + | program_basename = bb_basename(buf[0] == '-' ? buf + 1 : buf); |
| + | /* ^^^ note: must do it *before* replacing argv0's NUL with space */ |
| + | |
| + | /* Prevent stuff like this: |
| + | * echo 'sleep 999; exit' >`printf '\ec'`; sh ?c |
| + | * messing up top and ps output (or worse). |
| + | * This also replaces NULs with spaces, converting |
| + | * list of NUL-strings into one string. |
| + | */ |
| while (sz >= 0) { | |
| if ((unsigned char)(buf[sz]) < ' ') | |
| buf[sz] = ' '; | |
| sz--; | |
| } | |
| - | if (base[0] == '-') /* "-sh" (login shell)? */ |
| - | base++; |
| /* If comm differs from argv0, prepend "{comm} ". | |
| * 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) | |
| * I prefer to still treat argv0 "process foo bar" | |
| * as 'equal' to comm "process". | |
| */ | |
| - | if (strncmp(base, comm, comm_len) != 0) { |
| + | if (strncmp(program_basename, comm, comm_len) != 0) { |
| comm_len += 3; | |
| if (col > comm_len) | |
| memmove(buf + comm_len, buf, col - comm_len); | |
| @@ -602,6 +602,15 @@ static void parse_meminfo(unsigned long meminfo[MI_MAX]) | |
| fclose(f); | |
| } | |
| + | static void cmdline_to_line_buf_and_print(unsigned offset, unsigned pid, const char *comm) |
| + | { |
| + | int width = G.scr_width - offset; |
| + | if (width > 1) /* wider than to fit just the NUL? */ |
| + | read_cmdline(G.line_buf + offset, width, pid, comm); |
| + | //TODO: read_cmdline() sanitizes control chars, but not chars above 0x7e |
| + | print_line_buf(); |
| + | } |
| + | |
| static unsigned long display_header(void) | |
| { | |
| char *buf; | |
| @@ -789,9 +798,7 @@ static NOINLINE void display_process_list(void) | |
| IF_FEATURE_TOP_SMP_PROCESS(, s->last_seen_on_cpu) | |
| IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(, SHOW_STAT(pcpu)) | |
| ); | |
| - | if ((int)(G.scr_width - col) > 1) |
| - | read_cmdline(G.line_buf + col, G.scr_width - col, s->pid, s->comm); |
| - | print_line_buf(); |
| + | cmdline_to_line_buf_and_print(col, s->pid, s->comm); |
| /* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu, | |
| cur_jif.busy - prev_jif.busy, cur_jif.total - prev_jif.total); */ | |
| s++; | |
| @@ -910,14 +917,12 @@ static void ulltoa4_and_space(unsigned long long ul, char buf[5]) | |
| static NOINLINE void display_topmem_process_list(void) | |
| { | |
| - | #define HDR_STR " PID VSZ VSZRW RSS (SHR) DIRTY (SHR) STACK" |
| - | #define MIN_WIDTH sizeof(HDR_STR) |
| const topmem_status_t *s = topmem + G_scroll_ofs; | |
| char *cp, ch; | |
| display_topmem_header(); | |
| - | strcpy(G.line_buf, HDR_STR " COMMAND"); |
| + | strcpy(G.line_buf, " PID VSZ VSZRW RSS (SHR) DIRTY (SHR) STACK COMMAND"); |
| /* Mark the ^FIELD^ we sort by */ | |
| cp = &G.line_buf[5 + sort_field * 6]; | |
| ch = "^_"[inverted]; | |
| @@ -949,13 +954,9 @@ static NOINLINE void display_topmem_process_list(void) | |
| ulltoa5_and_space(s->dirty_sh, &G.line_buf[6*6]); | |
| ulltoa5_and_space(s->stack , &G.line_buf[7*6]); | |
| G.line_buf[8*6] = '\0'; | |
| - | if ((int)(G.scr_width - MIN_WIDTH) > 1) |
| - | read_cmdline(&G.line_buf[8*6], G.scr_width - MIN_WIDTH, s->pid, s->comm); |
| - | print_line_buf(); |
| + | cmdline_to_line_buf_and_print(8*6, s->pid, s->comm); |
| s++; | |
| } | |
| - | #undef HDR_STR |
| - | #undef MIN_WIDTH |
| } | |
| #endif /* end TOPMEM support */ | |