This implementation only supports specifying a single pid.

function                                             old     new   delta
format_process                                         -     176    +176
.rodata                                           100714  100751     +37
packed_usage                                       34927   34959     +32
procps_scan                                         1193    1205     +12
top_main                                            1115    1117      +2
pstree_main                                          375     377      +2
process_action                                      1204    1206      +2
pgrep_main                                           781     783      +2
lsof_main                                            279     281      +2
kill_main                                           1035    1037      +2
find_pid_by_name                                     262     264      +2
ps_main                                              692     634     -58
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 10/1 up/down: 271/-58)          Total: 213 bytes
   text   data     bss     dec     hex  filename
1040876  16443    1840  1059159 102957  busybox_old
1041089  16443    1840  1059372 102a2c  busybox_unstripped

Signed-off-by: Sertonix <serto...@posteo.net>
---
 include/libbb.h          |  3 ++-
 libbb/find_pid_by_name.c |  2 +-
 libbb/procps.c           | 11 +++++++----
 procps/kill.c            |  2 +-
 procps/lsof.c            |  2 +-
 procps/pgrep.c           |  2 +-
 procps/ps.c              | 28 ++++++++++++++++++++--------
 procps/pstree.c          |  2 +-
 procps/top.c             |  2 +-
 util-linux/mdev.c        |  2 +-
 10 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/include/libbb.h b/include/libbb.h
index 01cdb1bdc..64572ff56 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2132,10 +2132,11 @@ enum {
        PSSCAN_NICE     = (1 << 20) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
        PSSCAN_RUIDGID  = (1 << 21) * ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS,
        PSSCAN_TASKS    = (1 << 22) * ENABLE_FEATURE_SHOW_THREADS,
+       PSSCAN_FILTER   = (1 << 23),
 };
 //procps_status_t* alloc_procps_scan(void) FAST_FUNC;
 void free_procps_scan(procps_status_t* sp) FAST_FUNC;
-procps_status_t* procps_scan(procps_status_t* sp, int flags) FAST_FUNC;
+procps_status_t* procps_scan(procps_status_t* sp, int flags, unsigned pid) 
FAST_FUNC;
 /* Format cmdline (up to col chars) into char buf[size] */
 /* Puts [comm] if cmdline is empty (-> process is a kernel thread) */
 void read_cmdline(char *buf, int size, unsigned pid, const char *comm) 
FAST_FUNC;
diff --git a/libbb/find_pid_by_name.c b/libbb/find_pid_by_name.c
index fe13f7211..021b132ab 100644
--- a/libbb/find_pid_by_name.c
+++ b/libbb/find_pid_by_name.c
@@ -85,7 +85,7 @@ pid_t* FAST_FUNC find_pid_by_name(const char *procName)
        procps_status_t* p = NULL;
 
        pidList = xzalloc(sizeof(*pidList));
-       while ((p = procps_scan(p, 
PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN|PSSCAN_EXE))) {
+       while ((p = procps_scan(p, 
PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN|PSSCAN_EXE, 0))) {
                if (comm_match(p, procName)
                /* or we require argv0 to match (essential for matching 
reexeced /proc/self/exe)*/
                 || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0)
diff --git a/libbb/procps.c b/libbb/procps.c
index f56b71b21..fe1798cf6 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -92,6 +92,7 @@ static procps_status_t* FAST_FUNC alloc_procps_scan(void)
        }
        sp->shift_pages_to_kb = sp->shift_pages_to_bytes - 10;
        sp->dir = xopendir("/proc");
+       sp->pid = 0;
        return sp;
 }
 
@@ -279,16 +280,18 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec 
*total,
 }
 #endif
 
-procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
+procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags, 
unsigned pid)
 {
        if (!sp)
                sp = alloc_procps_scan();
 
+       if (pid)
+               goto got_pid;
+
        for (;;) {
                struct dirent *entry;
                char buf[PROCPS_BUFSIZE];
                long tasknice;
-               unsigned pid;
                int n;
                char filename[sizeof("/proc/%u/task/%u/cmdline") + 
sizeof(int)*3 * 2];
                char *filename_tail;
@@ -302,8 +305,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, 
int flags)
                        sp->task_dir = NULL;
                }
 #endif
-               entry = readdir(sp->dir);
-               if (entry == NULL) {
+               if ((flags & PSSCAN_FILTER) || (entry = readdir(sp->dir)) == 
NULL) {
                        free_procps_scan(sp);
                        return NULL;
                }
@@ -311,6 +313,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, 
int flags)
                pid = bb_strtou(entry->d_name, NULL, 10);
                if (errno)
                        continue;
+ got_pid:
 #if ENABLE_FEATURE_SHOW_THREADS
                if ((flags & PSSCAN_TASKS) && !sp->task_dir) {
                        /* We found another /proc/PID. Do not use it,
diff --git a/procps/kill.c b/procps/kill.c
index d4be18dd8..9be7350f4 100644
--- a/procps/kill.c
+++ b/procps/kill.c
@@ -219,7 +219,7 @@ int kill_main(int argc UNUSED_PARAM, char **argv)
                if (signo != SIGSTOP && signo != SIGCONT)
                        kill(-1, SIGSTOP);
                /* Signal all processes except those in our session */
-               while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID)) != NULL) {
+               while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID, 0)) != NULL) {
                        char **args;
 
                        if (p->sid == (unsigned)sid
diff --git a/procps/lsof.c b/procps/lsof.c
index 57e385c3f..28f804fae 100644
--- a/procps/lsof.c
+++ b/procps/lsof.c
@@ -46,7 +46,7 @@ int lsof_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
 {
        procps_status_t *proc = NULL;
 
-       while ((proc = procps_scan(proc, PSSCAN_PID|PSSCAN_EXE)) != NULL) {
+       while ((proc = procps_scan(proc, PSSCAN_PID|PSSCAN_EXE, 0)) != NULL) {
                char name[sizeof("/proc/%u/fd/0123456789") + sizeof(int)*3];
                unsigned baseofs;
                DIR *d_fd;
diff --git a/procps/pgrep.c b/procps/pgrep.c
index 04ae92a67..587ca4db6 100644
--- a/procps/pgrep.c
+++ b/procps/pgrep.c
@@ -164,7 +164,7 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv)
        matched_pid = 0;
        cmd_last = NULL;
        proc = NULL;
-       while ((proc = procps_scan(proc, scan_mask)) != NULL) {
+       while ((proc = procps_scan(proc, scan_mask, 0)) != NULL) {
                char *cmd;
                int cmdlen, match;
 
diff --git a/procps/ps.c b/procps/ps.c
index 5b521aebd..337a13cd0 100644
--- a/procps/ps.c
+++ b/procps/ps.c
@@ -59,10 +59,11 @@
 //usage:#if ENABLE_DESKTOP
 //usage:
 //usage:#define ps_trivial_usage
-//usage:       "[-o COL1,COL2=HEADER]" IF_FEATURE_SHOW_THREADS(" [-T]")
+//usage:       "[-o COL1,COL2=HEADER] [-p PID]" IF_FEATURE_SHOW_THREADS(" 
[-T]")
 //usage:#define ps_full_usage "\n\n"
 //usage:       "Show list of processes\n"
 //usage:     "\n       -o COL1,COL2=HEADER     Select columns for display"
+//usage:     "\n       -p PID                  Select pid to show"
 //usage:       IF_FEATURE_SHOW_THREADS(
 //usage:     "\n       -T                      Show threads"
 //usage:       )
@@ -553,10 +554,9 @@ int ps_main(int argc UNUSED_PARAM, char **argv)
 {
        procps_status_t *p;
        llist_t* opt_o = NULL;
+       unsigned opt_p = 0;
        char default_o[sizeof(DEFAULT_O_STR)];
-#if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS
        int opt;
-#endif
        enum {
                OPT_Z = (1 << 0),
                OPT_o = (1 << 1),
@@ -566,7 +566,8 @@ int ps_main(int argc UNUSED_PARAM, char **argv)
                OPT_e = (1 << 5),
                OPT_f = (1 << 6),
                OPT_l = (1 << 7),
-               OPT_T = (1 << 8) * ENABLE_FEATURE_SHOW_THREADS,
+               OPT_p = (1 << 8),
+               OPT_T = (1 << 9) * ENABLE_FEATURE_SHOW_THREADS,
        };
 
        INIT_G();
@@ -592,10 +593,8 @@ int ps_main(int argc UNUSED_PARAM, char **argv)
         * procps v3.2.7 supports -T and shows tids as SPID column,
         * it also supports -L where it shows tids as LWP column.
         */
-#if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS
        opt =
-#endif
-               getopt32(argv, "Zo:*aAdefl"IF_FEATURE_SHOW_THREADS("T"), 
&opt_o);
+               getopt32(argv, "Zo:*aAdeflp:+"IF_FEATURE_SHOW_THREADS("T"), 
&opt_o, &opt_p);
 
        if (opt_o) {
                do {
@@ -633,7 +632,20 @@ int ps_main(int argc UNUSED_PARAM, char **argv)
        format_header();
 
        p = NULL;
-       while ((p = procps_scan(p, need_flags)) != NULL) {
+       if (opt & OPT_p) {
+               if (!opt_p)
+                       bb_error_msg_and_die("bad -p argument, pid out of 
range");
+               need_flags |= PSSCAN_FILTER;
+               if ((p = procps_scan(p, need_flags, opt_p)) == NULL)
+                       return EXIT_FAILURE;
+               format_process(p);
+#if ENABLE_FEATURE_SHOW_THREADS
+               if (!(opt & OPT_T))
+#endif
+                       return EXIT_SUCCESS;
+       }
+
+       while ((p = procps_scan(p, need_flags, 0)) != NULL) {
                format_process(p);
        }
 
diff --git a/procps/pstree.c b/procps/pstree.c
index bf6ceed5a..9d3da9446 100644
--- a/procps/pstree.c
+++ b/procps/pstree.c
@@ -361,7 +361,7 @@ static void mread_proc(void)
 #endif
        int flags = PSSCAN_COMM | PSSCAN_PID | PSSCAN_PPID | PSSCAN_UIDGID | 
PSSCAN_TASKS;
 
-       while ((p = procps_scan(p, flags)) != NULL) {
+       while ((p = procps_scan(p, flags, 0)) != NULL) {
 #if ENABLE_FEATURE_SHOW_THREADS
                if (p->pid != p->main_thread_pid)
                        handle_thread(p->comm, p->pid, parent, p->uid);
diff --git a/procps/top.c b/procps/top.c
index 09d31c673..87c392a12 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -1247,7 +1247,7 @@ int top_main(int argc UNUSED_PARAM, char **argv)
 
                /* read process IDs & status for all the processes */
                ntop = 0;
-               while ((p = procps_scan(p, scan_mask)) != NULL) {
+               while ((p = procps_scan(p, scan_mask, 0)) != NULL) {
                        int n;
 
                        IF_FEATURE_TOPMEM(if (scan_mask != TOPMEM_MASK)) {
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index e98d46743..7ab7a191d 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -1058,7 +1058,7 @@ wait_for_seqfile(unsigned expected_seq)
 static void signal_mdevs(unsigned my_pid)
 {
        procps_status_t* p = NULL;
-       while ((p = procps_scan(p, PSSCAN_ARGV0)) != NULL) {
+       while ((p = procps_scan(p, PSSCAN_ARGV0, 0)) != NULL) {
                if (p->pid != my_pid
                 && p->argv0
                 && strcmp(bb_basename(p->argv0), "mdev") == 0
-- 
2.45.2

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to