[PATCH v8 07/14] libbb: implement bb_system using spawn_and_wait

Nadav Tasher tashernadav at gmail.com
Sun Mar 9 23:55:29 UTC 2025


Implemented bb_system using spawn_and_wait in conjuction with "sh",
to allow bb_system to execute the internal shell when using the
FEATURE_PREFER_APPLETS config option.

When FEATURE_PREFER_APPLETS is disabled, libc "system()" is used.

Signed-off-by: Nadav Tasher <tashernadav at gmail.com>
---
 include/libbb.h            |  1 +
 libbb/vfork_daemon_rexec.c | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/include/libbb.h b/include/libbb.h
index c8814ce50..4da4e79f5 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1305,6 +1305,7 @@ int wait_for_exitstatus(pid_t pid) FAST_FUNC;
 /************************************************************************/
 /* Same as wait4pid(spawn(argv)), but with NOFORK/NOEXEC if configured: */
 int spawn_and_wait(char **argv) FAST_FUNC;
+int bb_system(const char *command) FAST_FUNC;
 /* Does NOT check that applet is NOFORK, just blindly runs it */
 int run_nofork_applet(int applet_no, char **argv) FAST_FUNC;
 void run_noexec_applet_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC;
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index a3de7e742..eff1bfd6d 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -249,6 +249,40 @@ int FAST_FUNC spawn_and_wait(char **argv)
 	return wait4pid(rc);
 }
 
+int FAST_FUNC bb_system(const char *command) {
+#if ENABLE_FEATURE_PREFER_APPLETS
+	int return_code;
+
+	/* we use sh because it might launch ash,
+	 * and this is also what system() does. */
+	char system_arg0[] = "sh", system_arg1[] = "-c", *system_arg2, *system_argv[4];
+	
+	/* when command is NULL, return a nonzero value,
+	 * This indicates there is a shell available.
+	 */
+	if (command == NULL)
+		return 1;
+
+	/* we must ensure command stays unchanged. */
+	system_arg2 = xstrdup(command);
+
+	system_argv[0] = system_arg0;
+	system_argv[1] = system_arg1;
+	system_argv[2] = system_arg2;
+	system_argv[3] = NULL;
+
+	/* spawn the shell and wait for it to return. */
+	return_code = spawn_and_wait(system_argv);
+
+	/* free the allocated command copy */
+	free(system_arg2);
+
+	return return_code;
+#else
+	return system(command);
+#endif
+}
+
 #if !BB_MMU
 void FAST_FUNC re_exec(char **argv)
 {
-- 
2.43.0



More information about the busybox mailing list