changeset 956:caa05719070f

Start of TOYBOX_SINGLE support, for building standalone commands with no multiplexer.
author Rob Landley <rob@landley.net>
date Fri, 19 Jul 2013 02:03:02 -0500
parents 144d5ba7d410
children 1ec29d7540e2
files Config.in lib/xwrap.c main.c
diffstat 3 files changed, 44 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/Config.in	Thu Jul 18 18:20:03 2013 -0500
+++ b/Config.in	Fri Jul 19 02:03:02 2013 -0500
@@ -17,6 +17,12 @@
 	  With no arguments, shows available commands. First argument is
 	  name of a command to run, followed by any arguments to that command.
 
+config TOYBOX_SINGLE
+	bool
+	default n
+	help
+	  Build a single toybox command standalone with no multiplexer.
+
 config TOYBOX_SUID
 	bool "SUID support"
 	default y
--- a/lib/xwrap.c	Thu Jul 18 18:20:03 2013 -0500
+++ b/lib/xwrap.c	Fri Jul 19 02:03:02 2013 -0500
@@ -127,7 +127,7 @@
 // with a path isn't a builtin, so /bin/sh won't match the builtin sh.
 void xexec(char **argv)
 {
-  toy_exec(argv);
+  if (!CFG_TOYBOX_SINGLE) toy_exec(argv);
   execvp(argv[0], argv);
 
   perror_exit("exec %s", argv[0]);
--- a/main.c	Thu Jul 18 18:20:03 2013 -0500
+++ b/main.c	Fri Jul 19 02:03:02 2013 -0500
@@ -60,6 +60,26 @@
 #include "generated/newtoys.h"
 0;  // Ends the opts || opts || opts...
 
+// Subset of init needed by singlemain
+static void toy_singleinit(struct toy_list *which, char *argv[])
+{
+  toys.which = which;
+  toys.argv = argv;
+
+  if (CFG_TOYBOX_HELP_DASHDASH && argv[1] && !strcmp(argv[1], "--help")) {
+    show_help();
+    xexit();
+  }
+
+  if (NEED_OPTIONS && which->options) get_optflags();
+  else {
+    toys.optargs = argv+1;
+    for (toys.optc=0; toys.optargs[toys.optc]; toys.optc++);
+  }
+  toys.old_umask = umask(0);
+  if (!(which->flags & TOYFLAG_UMASK)) umask(toys.old_umask);
+}
+
 // Setup toybox global state for this command.
 
 void toy_init(struct toy_list *which, char *argv[])
@@ -82,21 +102,8 @@
   if (toys.optargs != toys.argv+1) free(toys.optargs);
   memset(&toys, 0, offsetof(struct toy_context, rebound));
 
-  toys.which = which;
-  toys.argv = argv;
-
-  if (CFG_TOYBOX_HELP_DASHDASH && argv[1] && !strcmp(argv[1], "--help")) {
-    show_help();
-    xexit();
-  }
-
-  if (NEED_OPTIONS && which->options) get_optflags();
-  else {
-    toys.optargs = argv+1;
-    for (toys.optc=0; toys.optargs[toys.optc]; toys.optc++);
-  }
-  toys.old_umask = umask(0);
-  if (!(which->flags & TOYFLAG_UMASK)) umask(toys.old_umask);
+  // Subset of init needed by singlemain.
+  toy_singleinit(which, argv);
 }
 
 // Like exec() but runs an internal toybox command instead of another file.
@@ -160,12 +167,20 @@
 {
   if (CFG_TOYBOX_I18N) setlocale(LC_ALL, "");
 
-  // Trim path off of command name
-  *argv = basename(*argv);
+  if (!CFG_TOYBOX_SINGLE) {
+    // Trim path off of command name
+    *argv = basename(*argv);
 
-  // Call the multiplexer, adjusting this argv[] to be its' argv[1].
-  // (It will adjust it back before calling toy_exec().)
-  toys.argv = argv-1;
-  toybox_main();
-  return 0;
+    // Call the multiplexer, adjusting this argv[] to be its' argv[1].
+    // (It will adjust it back before calling toy_exec().)
+    toys.argv = argv-1;
+    toybox_main();
+  } else {
+    // a single toybox command built standalone with no multiplexer
+    toy_singleinit(toy_list, argv);
+    toy_list->toy_main();
+    if (fflush(NULL) || ferror(stdout)) perror_exit("write");
+  }
+
+  return toys.exitval;
 }