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)
signature.asc
Description: Digital signature