PATCH: replacing exec*p with BB_EXEC*P

Gabriel L. Somlo somlo at cmu.edu
Mon Feb 5 16:40:26 UTC 2007


Denis, Bernhard,

Here's a version that provides both a bb_execvp() and a bb_execlp()
function. The latter is a simplified version of the glibc one, but
returns E2BIG when more than 16 arguments are passed into it, and does
have the code that would grow the argv array dynamically while reading
its varargs. That should not be a problem, as all execlp calls I've
seen so far in busybox have maybe four arguments max...

Cheers,
Gabriel



diff -NarU5 busybox-svn-17770.orig/include/libbb.h busybox-svn-17770/include/libbb.h
--- busybox-svn-17770.orig/include/libbb.h	2007-02-04 16:25:53.000000000 -0500
+++ busybox-svn-17770/include/libbb.h	2007-02-05 11:33:12.000000000 -0500
@@ -560,14 +560,14 @@
 int execable_file(const char *name);
 char *find_execable(const char *filename);
 int exists_execable(const char *filename);
 
 #ifdef ENABLE_FEATURE_EXEC_PREFER_APPLETS
-#define BB_EXECVP(prog,cmd) \
-	execvp((find_applet_by_name(prog)) ? CONFIG_BUSYBOX_EXEC_PATH : prog, cmd)
-#define BB_EXECLP(prog,cmd,...) \
-	execlp((find_applet_by_name(prog)) ? CONFIG_BUSYBOX_EXEC_PATH : prog, cmd, __VA_ARGS__)
+int bb_execvp(const char *file, char *const argv[]);
+int bb_execlp(const char *file, const char *arg, ...);
+#define BB_EXECVP(prog,cmd) bb_execvp(prog,cmd)
+#define BB_EXECLP(prog,cmd,...) bb_execlp(prog,cmd, __VA_ARGS__) 
 #else
 #define BB_EXECVP(prog,cmd) execvp(prog,cmd)
 #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd, __VA_ARGS__) 
 #endif
 
diff -NarU5 busybox-svn-17770.orig/libbb/execable.c busybox-svn-17770/libbb/execable.c
--- busybox-svn-17770.orig/libbb/execable.c	2007-02-04 16:25:51.000000000 -0500
+++ busybox-svn-17770/libbb/execable.c	2007-02-05 11:30:55.000000000 -0500
@@ -57,5 +57,42 @@
 		free(ret);
 		return 1;
 	}
 	return 0;
 }
+
+#ifdef ENABLE_FEATURE_EXEC_PREFER_APPLETS
+/* just like the real execvp, but try to launch an applet named 'file' first
+ */
+int bb_execvp(const char *file, char *const argv[])
+{
+	return execvp(find_applet_by_name(file) ? CONFIG_BUSYBOX_EXEC_PATH : file,
+					argv);
+}
+
+/* just like the real execlp, but try to launch an applet named 'file' first
+ * (since there's no good way to handle varargs here, we unroll execlp and
+ *  replace the execvp call with a bb_execvp call :)
+ */
+int bb_execlp (const char *file, const char *arg, ...)
+{
+	#define ARGV_MAX 16
+	const char *argv[ARGV_MAX];
+	unsigned int i = 0;
+	va_list args;
+
+	argv[0] = arg;
+
+	va_start(args, arg);
+	while (argv[i++] != NULL && i < ARGV_MAX) {
+		argv[i] = va_arg(args, const char *);
+	}
+	va_end(args);
+
+	if (i >= ARGV_MAX) {
+		errno = E2BIG;
+		return -1;
+	}
+
+	return bb_execvp(file, (char *const *)argv);
+}
+#endif



More information about the busybox mailing list