diff options
Diffstat (limited to 'libbb/procps.c')
-rw-r--r-- | libbb/procps.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/libbb/procps.c b/libbb/procps.c index 58772d4e9..b5582edfa 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -358,7 +358,14 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
358 | sp->gid = sb.st_gid; | 358 | sp->gid = sb.st_gid; |
359 | } | 359 | } |
360 | 360 | ||
361 | if (flags & PSSCAN_STAT) { | 361 | /* These are all retrieved from proc/NN/stat in one go: */ |
362 | if (flags & (PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID | ||
363 | | PSSCAN_COMM | PSSCAN_STATE | ||
364 | | PSSCAN_VSZ | PSSCAN_RSS | ||
365 | | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_START_TIME | ||
366 | | PSSCAN_TTY | PSSCAN_NICE | ||
367 | | PSSCAN_CPU) | ||
368 | ) { | ||
362 | char *cp, *comm1; | 369 | char *cp, *comm1; |
363 | int tty; | 370 | int tty; |
364 | #if !ENABLE_FEATURE_FAST_TOP | 371 | #if !ENABLE_FEATURE_FAST_TOP |
@@ -562,18 +569,47 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
562 | void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) | 569 | void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) |
563 | { | 570 | { |
564 | int sz; | 571 | int sz; |
565 | char filename[sizeof("/proc//cmdline") + sizeof(int)*3]; | 572 | char filename[sizeof("/proc/%u/cmdline") + sizeof(int)*3]; |
566 | 573 | ||
567 | sprintf(filename, "/proc/%u/cmdline", pid); | 574 | sprintf(filename, "/proc/%u/cmdline", pid); |
568 | sz = open_read_close(filename, buf, col - 1); | 575 | sz = open_read_close(filename, buf, col - 1); |
569 | if (sz > 0) { | 576 | if (sz > 0) { |
577 | const char *base; | ||
578 | int comm_len; | ||
579 | |||
570 | buf[sz] = '\0'; | 580 | buf[sz] = '\0'; |
571 | while (--sz >= 0 && buf[sz] == '\0') | 581 | while (--sz >= 0 && buf[sz] == '\0') |
572 | continue; | 582 | continue; |
573 | do { | 583 | base = bb_basename(buf); /* before we replace argv0's NUL with space */ |
584 | while (sz >= 0) { | ||
574 | if ((unsigned char)(buf[sz]) < ' ') | 585 | if ((unsigned char)(buf[sz]) < ' ') |
575 | buf[sz] = ' '; | 586 | buf[sz] = ' '; |
576 | } while (--sz >= 0); | 587 | sz--; |
588 | } | ||
589 | |||
590 | /* If comm differs from argv0, prepend "{comm} ". | ||
591 | * It allows to see thread names set by prctl(PR_SET_NAME). | ||
592 | */ | ||
593 | if (base[0] == '-') /* "-sh" (login shell)? */ | ||
594 | base++; | ||
595 | comm_len = strlen(comm); | ||
596 | /* Why compare up to comm_len, not COMM_LEN-1? | ||
597 | * Well, some processes rewrite argv, and use _spaces_ there | ||
598 | * while rewriting. (KDE is observed to do it). | ||
599 | * I prefer to still treat argv0 "process foo bar" | ||
600 | * as 'equal' to comm "process". | ||
601 | */ | ||
602 | if (strncmp(base, comm, comm_len) != 0) { | ||
603 | comm_len += 3; | ||
604 | if (col > comm_len) | ||
605 | memmove(buf + comm_len, buf, col - comm_len); | ||
606 | snprintf(buf, col, "{%s}", comm); | ||
607 | if (col <= comm_len) | ||
608 | return; | ||
609 | buf[comm_len - 1] = ' '; | ||
610 | buf[col - 1] = '\0'; | ||
611 | } | ||
612 | |||
577 | } else { | 613 | } else { |
578 | snprintf(buf, col, "[%s]", comm); | 614 | snprintf(buf, col, "[%s]", comm); |
579 | } | 615 | } |