--- busybox-1.10.1/debianutils/start_stop_daemon.c	Sat Apr 19 05:50:30 2008
+++ busybox-1.10.1-ssd/debianutils/start_stop_daemon.c	Tue Apr 22 03:13:13 2008
@@ -11,7 +11,6 @@
 /* NB: we have a problem here with /proc/NN/exe usage, similar to
  * one fixed in killall/pidof */
 
-#include <getopt.h>
 #include <sys/resource.h>
 
 /* Override ENABLE_FEATURE_PIDFILE */
@@ -33,6 +32,7 @@
 	int user_id;
 	smallint quiet;
 	smallint signal_nr;
+	struct stat execstat;
 };
 #define G (*(struct globals*)&bb_common_bufsiz1)
 #define found             (G.found               )
@@ -43,6 +43,7 @@
 #define user_id           (G.user_id             )
 #define quiet             (G.quiet               )
 #define signal_nr         (G.signal_nr           )
+#define execstat          (G.execstat            )
 #define INIT_G() \
         do { \
 		user_id = -1; \
@@ -50,25 +51,21 @@
         } while (0)
 
 
-static int pid_is_exec(pid_t pid, const char *name)
+static int pid_is_exec(pid_t pid)
 {
+	struct stat st;
 	char buf[sizeof("/proc//exe") + sizeof(int)*3];
-	char *execbuf;
-	int n;
 
 	sprintf(buf, "/proc/%u/exe", pid);
-	n = strlen(name) + 1;
-	execbuf = xzalloc(n + 1);
-	readlink(buf, execbuf, n);
-	/* if readlink fails because link target is longer than strlen(name),
-	 * execbuf still contains "", and strcmp will return !0. */
-	n = strcmp(execbuf, name);
-	if (ENABLE_FEATURE_CLEAN_UP)
-		free(execbuf);
-	return !n; /* nonzero (true) if execbuf == name */
+	if (stat(buf, &st) < 0)
+		return 0;
+	if (st.st_dev == execstat.st_dev
+	 && st.st_ino == execstat.st_ino)
+		return 1;
+	return 0;
 }
 
-static int pid_is_user(int pid, int uid)
+static int pid_is_user(int pid)
 {
 	struct stat sb;
 	char buf[sizeof("/proc/") + sizeof(int)*3];
@@ -76,42 +73,39 @@
 	sprintf(buf, "/proc/%u", pid);
 	if (stat(buf, &sb) != 0)
 		return 0;
-	return (sb.st_uid == uid);
+	return (sb.st_uid == user_id);
 }
 
-static int pid_is_cmd(pid_t pid, const char *name)
+static int pid_is_cmd(pid_t pid)
 {
-	char fname[sizeof("/proc//stat") + sizeof(int)*3];
-	char *buf;
-	int r = 0;
+	char buf[256]; /* is it big enough? */
+	char *p, *pe;
 
-	sprintf(fname, "/proc/%u/stat", pid);
-	buf = xmalloc_open_read_close(fname, NULL);
-	if (buf) {
-		char *p = strchr(buf, '(');
-		if (p) {
-			char *pe = strrchr(++p, ')');
-			if (pe) {
-				*pe = '\0';
-				r = !strcmp(p, name);
-			}
-		}
-		free(buf);
-	}
-	return r;
+	sprintf(buf, "/proc/%u/stat", pid);
+	if (open_read_close(buf, buf, sizeof(buf) - 1) < 0)
+		return 0;
+	buf[sizeof(buf) - 1] = '\0'; /* paranoia */
+	p = strchr(buf, '(');
+	if (!p)
+		return 0;
+	pe = strrchr(++p, ')');
+	if (!pe)
+		return 0;
+	*pe = '\0';
+	return !strcmp(p, cmdname);
 }
 
 static void check(int pid)
 {
 	struct pid_list *p;
 
-	if (execname && !pid_is_exec(pid, execname)) {
+	if (execname && !pid_is_exec(pid)) {
 		return;
 	}
-	if (userspec && !pid_is_user(pid, user_id)) {
+	if (userspec && !pid_is_user(pid)) {
 		return;
 	}
-	if (cmdname && !pid_is_cmd(pid, cmdname)) {
+	if (cmdname && !pid_is_cmd(pid)) {
 		return;
 	}
 	p = xmalloc(sizeof(*p));
@@ -148,9 +142,16 @@
 	procdir = xopendir("/proc");
 
 	pid = 0;
-	while ((entry = readdir(procdir)) != NULL) {
+	while(1) {
+		errno = 0; /* clear any previous error */
+		entry = readdir(procdir);
+// TODO: check for exact errno(s) which mean that we got stale entry
+		if (errno) /* Stale entry, process has died after opendir */
+			continue;
+		if (!entry) /* EOF, no more entries */
+			break;
 		pid = bb_strtou(entry->d_name, NULL, 10);
-		if (errno)
+		if (errno) /* NaN */
 			continue;
 		check(pid);
 	}
@@ -165,8 +166,6 @@
 	struct pid_list *p;
 	int killed = 0;
 
-	do_procinit();
-
 	if (cmdname) {
 		if (ENABLE_FEATURE_CLEAN_UP) what = xstrdup(cmdname);
 		if (!ENABLE_FEATURE_CLEAN_UP) what = cmdname;
@@ -251,7 +250,7 @@
 };
 
 int start_stop_daemon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-int start_stop_daemon_main(int argc, char **argv)
+int start_stop_daemon_main(int argc ATTRIBUTE_UNUSED, char **argv)
 {
 	unsigned opt;
 	char *signame;
@@ -293,7 +292,7 @@
 //		if (retry_arg)
 //			retries = xatoi_u(retry_arg);
 //	)
-	argc -= optind;
+	//argc -= optind;
 	argv += optind;
 
 	if (userspec) {
@@ -301,13 +300,15 @@
 		if (errno)
 			user_id = xuname2uid(userspec);
 	}
+	if (execname)
+		xstat(execname, &execstat);
 
+	do_procinit(); /* Both start and stop needs to know current processes */
+
 	if (opt & CTX_STOP) {
 		int i = do_stop();
 		return (opt & OPT_OKNODO) ? 0 : (i <= 0);
 	}
-
-	do_procinit();
 
 	if (found) {
 		if (!quiet)
