From cd7001f7055c3fc2d6298ab9e3befe91e951c652 Mon Sep 17 00:00:00 2001
From: Denis Vlasenko <vda.linux@googlemail.com>
Date: Mon, 9 Apr 2007 21:32:30 +0000
Subject: factor out NOFORK/NOEXEC code from find. Use it for xargs too.

---
 libbb/vfork_daemon_rexec.c | 42 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 3 deletions(-)

(limited to 'libbb')

diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index ff2b0bceb..d25693917 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -16,7 +16,7 @@
  */
 
 #include <paths.h>
-#include "libbb.h"
+#include "busybox.h" /* for struct BB_applet */
 
 /* This does a fork/exec in one call, using vfork().  Returns PID of new child,
  * -1 for failure.  Runs argv[0], searching path if that has no / in it. */
@@ -72,7 +72,8 @@ int wait4pid(int pid)
 	int status;
 
 	if (pid <= 0) {
-		/*errno = ECHILD; -- wrong. we expect errno to be set from failed exec */
+		/*errno = ECHILD; -- wrong. */
+		/* we expect errno to be already set from failed [v]fork/exec */
 		return -1;
 	}
 	if (waitpid(pid, &status, 0) == -1)
@@ -80,7 +81,7 @@ int wait4pid(int pid)
 	if (WIFEXITED(status))
 		return WEXITSTATUS(status);
 	if (WIFSIGNALED(status))
-		return WTERMSIG(status) + 10000;
+		return WTERMSIG(status) + 1000;
 	return 0;
 }
 
@@ -99,6 +100,41 @@ int wait_pid(int *wstat, int pid)
 	return r;
 }
 
+int spawn_and_wait(char **argv)
+{
+	int rc;
+
+	if (ENABLE_FEATURE_EXEC_PREFER_APPLETS) {
+		const struct BB_applet *a = find_applet_by_name(argv[0]);
+		if (a && (a->nofork
+#ifndef BB_NOMMU
+			 || a->noexec /* NOEXEC cannot be used on NOMMU */
+#endif
+		)) {
+			int argc = 1;
+			char **pp = argv;
+			while (*++pp)
+				argc++;
+#ifdef BB_NOMMU
+			return a->main(argc, argv);
+#else
+			if (a->nofork)
+				return a->main(argc, argv);
+			/* a->noexec is true */
+			rc = fork();
+			if (rc)
+				goto w;
+			/* child */
+			current_applet = a;
+			run_current_applet_and_exit(argc, argv);
+#endif
+		}
+	}
+	rc = spawn(argv);
+ w:
+	return wait4pid(rc);
+}
+
 #if 0 //ndef BB_NOMMU
 // Die with an error message if we can't daemonize.
 void xdaemon(int nochdir, int noclose)
-- 
cgit v1.2.3-55-g6feb