[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#472846: busybox: Regression in pidof: no longer lists 'debian-installer' processes



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 to: