tags 472846 patch
thanks

On Thu, Mar 27, 2008 at 10:14:54AM +0100, Bastian Blank wrote:
> Looks like a feature request.

The attached patch does this.

Bastian

-- 
No one can guarantee the actions of another.
                -- Spock, "Day of the Dove", stardate unknown
Index: libbb/procps.c
===================================================================
--- libbb/procps.c      (revision 21493)
+++ libbb/procps.c      (working copy)
@@ -110,7 +110,8 @@
 void free_procps_scan(procps_status_t* sp)
 {
        closedir(sp->dir);
-       free(sp->argv0);
+       free(sp->args);
+       free(sp->argv[0]);
        USE_SELINUX(free(sp->context);)
        free(sp);
 }
@@ -378,13 +379,24 @@
                        }
                }
 #else
-               if (flags & (PSSCAN_ARGV0|PSSCAN_ARGVN)) {
-                       free(sp->argv0);
-                       sp->argv0 = NULL;
+               if (flags & (PSSCAN_ARGV0|PSSCAN_ARGVN|PSSCAN_ARGV)) {
+                       free(sp->args);
+                       sp->args = NULL;
+                       free(sp->argv[0]);
+                       memset(sp->argv, 0, sizeof(sp->argv));
                        strcpy(filename_tail, "/cmdline");
                        n = read_to_buf(filename, buf);
                        if (n <= 0)
                                break;
+                       if (flags & PSSCAN_ARGV) {
+                               int i = 1, j = 0;
+                               char *t = malloc(n + 1);
+                               sp->argv[0] = t;
+                               memcpy(t, buf, n + 1);
+                               for (; j < n && i < (sizeof(sp->argv) / 
sizeof(sp->argv[0])); j++)
+                                       if (t[j] == 0)
+                                               sp->argv[i++] = &t[j + 1];
+                       }
 #if ENABLE_PGREP || ENABLE_PKILL
                        if (flags & PSSCAN_ARGVN) {
                                do {
@@ -394,7 +406,7 @@
                                } while (n);
                        }
 #endif
-                       sp->argv0 = xstrdup(buf);
+                       sp->args = xstrdup(buf);
                }
 #endif
                break;
Index: libbb/find_pid_by_name.c
===================================================================
--- libbb/find_pid_by_name.c    (revision 21493)
+++ libbb/find_pid_by_name.c    (working copy)
@@ -38,6 +38,31 @@
 and therefore comm field contains "exe".
 */
 
+static inline int check_comm(procps_status_t *p, const char* procName, int 
script_also)
+{
+       /* we require comm to match and to not be truncated */
+       /* in Linux, if comm is 15 chars, it may be a truncated
+        * name, so we don't allow that to match */
+       return script_also && !p->comm[sizeof(p->comm)-2] && strcmp(p->comm, 
procName) == 0;
+}
+
+static inline int check_argv(procps_status_t *p, const char* procName, int 
script_also)
+{
+       int i;
+       if (script_also)
+               for (i = 1; i < (sizeof(p->argv) / sizeof(p->argv[0])) && 
p->argv[i]; i++) {
+                       if (p->argv[i][0] != '-') {
+                               if (strcmp(bb_basename(p->argv[i]), procName) 
== 0)
+                                       return 1;
+                               break;
+                       }
+               }
+
+       /* or we require argv0 to match (essential for matching reexeced 
/proc/self/exe)*/
+       return p->args && strcmp(bb_basename(p->args), procName) == 0;
+       /* TOOD: we can also try /proc/NUM/exe link, do we want that? */
+}
+
 /* find_pid_by_name()
  *
  *  Modified by Vladimir Oleynik for use with libbb/procps.c
@@ -48,23 +73,19 @@
  *  Returns a list of all matching PIDs
  *  It is the caller's duty to free the returned pidlist.
  */
-pid_t* find_pid_by_name(const char* procName)
+pid_t* find_pid_by_name(const char* procName, int script_also)
 {
        pid_t* pidList;
        int i = 0;
        procps_status_t* p = NULL;
+       int flags = PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGV0;
+       if (script_also)
+               flags |= PSSCAN_ARGV;
 
        pidList = xmalloc(sizeof(*pidList));
-       while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGV0))) {
-               if (
-               /* we require comm to match and to not be truncated */
-               /* in Linux, if comm is 15 chars, it may be a truncated
-                * name, so we don't allow that to match */
-                   (!p->comm[sizeof(p->comm)-2] && strcmp(p->comm, procName) 
== 0)
-               /* or we require argv0 to match (essential for matching 
reexeced /proc/self/exe)*/
-                || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0)
-               /* TOOD: we can also try /proc/NUM/exe link, do we want that? */
-               ) {
+       while ((p = procps_scan(p, flags))) {
+               if (check_comm(p, procName, script_also)
+                   || check_argv(p, procName, script_also)) {
                        pidList = xrealloc(pidList, sizeof(*pidList) * (i+2));
                        pidList[i++] = p->pid;
                }
Index: include/libbb.h
===================================================================
--- include/libbb.h     (revision 21493)
+++ include/libbb.h     (working copy)
@@ -1073,7 +1073,8 @@
        uint8_t shift_pages_to_bytes;
        uint8_t shift_pages_to_kb;
 /* Fields are set to 0/NULL if failed to determine (or not requested) */
-       char *argv0;
+       char *args;
+       char *argv[16];
        USE_SELINUX(char *context;)
        /* Everything below must contain no ptrs to malloc'ed data:
         * it is memset(0) for each process in procps_scan() */
@@ -1123,6 +1124,7 @@
        PSSCAN_ARGVN    = (1 << 16) * (ENABLE_PGREP | ENABLE_PKILL),
        USE_SELINUX(PSSCAN_CONTEXT = 1 << 17,)
        PSSCAN_START_TIME = 1 << 18,
+       PSSCAN_ARGV     = 1 << 19,
        /* These are all retrieved from proc/NN/stat in one go: */
        PSSCAN_STAT     = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID
                        | PSSCAN_COMM | PSSCAN_STATE
@@ -1136,7 +1138,7 @@
 /* Format cmdline (up to col chars) into char buf[col+1] */
 /* Puts [comm] if cmdline is empty (-> process is a kernel thread) */
 void read_cmdline(char *buf, int col, unsigned pid, const char *comm);
-pid_t *find_pid_by_name(const char* procName);
+pid_t *find_pid_by_name(const char* procName, int script_also);
 pid_t *pidlist_reverse(pid_t *pidList);
 
 
Index: selinux/sestatus.c
===================================================================
--- selinux/sestatus.c  (revision 21493)
+++ selinux/sestatus.c  (working copy)
@@ -116,7 +116,7 @@
 
        /* [process] context */
        for (i = 0; pc[i] != NULL; i++) {
-               pidList = find_pid_by_name(bb_basename(pc[i]));
+               pidList = find_pid_by_name(bb_basename(pc[i]), 0);
                if (pidList[0] > 0 && getpidcon(pidList[0], &con) == 0) {
                        printf(COL_FMT "%s\n", pc[i], con);
                        if (ENABLE_FEATURE_CLEAN_UP)
Index: init/halt.c
===================================================================
--- init/halt.c (revision 21493)
+++ init/halt.c (working copy)
@@ -76,7 +76,7 @@
        /* Perform action. */
        if (ENABLE_INIT && !(flags & 4)) {
                if (ENABLE_FEATURE_INITRD) {
-                       pid_t *pidlist = find_pid_by_name("linuxrc");
+                       pid_t *pidlist = find_pid_by_name("linuxrc", 0);
                        if (pidlist[0] > 0)
                                rc = kill(pidlist[0], signals[which]);
                        if (ENABLE_FEATURE_CLEAN_UP)
Index: procps/pidof.c
===================================================================
--- procps/pidof.c      (revision 21493)
+++ procps/pidof.c      (working copy)
@@ -10,8 +10,10 @@
 #include "libbb.h"
 
 enum {
+       OPTBIT_SCRIPT,
        USE_FEATURE_PIDOF_SINGLE(OPTBIT_SINGLE,)
        USE_FEATURE_PIDOF_OMIT(  OPTBIT_OMIT  ,)
+       OPT_SCRIPT = 1 << OPTBIT_SCRIPT,
        OPT_SINGLE = USE_FEATURE_PIDOF_SINGLE((1<<OPTBIT_SINGLE)) + 0,
        OPT_OMIT   = USE_FEATURE_PIDOF_OMIT(  (1<<OPTBIT_OMIT  )) + 0,
 };
@@ -28,7 +30,7 @@
 #endif
 
        /* do unconditional option parsing */
-       opt = getopt32(argv, ""
+       opt = getopt32(argv, "x"
                        USE_FEATURE_PIDOF_SINGLE ("s")
                        USE_FEATURE_PIDOF_OMIT("o:", &omits));
 
@@ -53,7 +55,7 @@
                pid_t *pl;
 
                /* reverse the pidlist like GNU pidof does.  */
-               pidList = pidlist_reverse(find_pid_by_name(*argv));
+               pidList = pidlist_reverse(find_pid_by_name(*argv, opt & 
OPT_SCRIPT));
                for (pl = pidList; *pl; pl++) {
 #if ENABLE_FEATURE_PIDOF_OMIT
                        if (opt & OPT_OMIT) {
Index: procps/pgrep.c
===================================================================
--- procps/pgrep.c      (revision 21493)
+++ procps/pgrep.c      (working copy)
@@ -110,7 +110,7 @@
                char *cmd;
                if (proc->pid == pid)
                        continue;
-               cmd = proc->argv0;
+               cmd = proc->args;
                if (!cmd)
                        cmd = proc->comm;
                /* NB: OPT_INVERT is always 0 or 1 */
Index: procps/kill.c
===================================================================
--- procps/kill.c       (revision 21493)
+++ procps/kill.c       (working copy)
@@ -139,7 +139,7 @@
                while (arg) {
                        pid_t* pidList;
 
-                       pidList = find_pid_by_name(arg);
+                       pidList = find_pid_by_name(arg, 0);
                        if (*pidList == 0) {
                                errors++;
                                if (!quiet)

Attachment: signature.asc
Description: Digital signature

Reply via email to