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