[git commit master 1/1] hush: use FEATURE_SH_NOFORK to enable NOFORK trick

Denys Vlasenko vda.linux at googlemail.com
Wed Feb 2 17:38:57 UTC 2011


commit: http://git.busybox.net/busybox/commit/?id=b72baeb00328576df415f9a4b4f3d5f202e3be11
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

Also expands docs

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 docs/nofork_noexec.txt |   27 +++++++++++++++++++++++----
 include/libbb.h        |    1 +
 shell/Config.src       |    9 +++++----
 shell/hush.c           |   11 +++++------
 4 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/docs/nofork_noexec.txt b/docs/nofork_noexec.txt
index 06c789a..c58f5a8 100644
--- a/docs/nofork_noexec.txt
+++ b/docs/nofork_noexec.txt
@@ -44,9 +44,11 @@ NOEXEC trick is disabled for NOMMU build.
 	NOFORK
 
 NOFORK applet should work correctly if another applet simply runs
-<applet>_main(argc,argv) and then continues with its business (xargs,
-find, shells can do it). This poses much more serious limitations
-on what applet can/cannot do:
+<applet>_main(argc,argv) and then continues with its business.
+xargs, find, shells do it (grep for "spawn_and_wait" and
+"run_nofork_applet" to find more users).
+
+This poses much more serious limitations on what applet can do:
 
 * all NOEXEC limitations apply.
 * do not ever exit() or exec().
@@ -56,7 +58,7 @@ on what applet can/cannot do:
     is taken from xfunc_error_retval.
   - fflush_stdout_and_exit(n) is ok to use.
 * do not use shared global data, or save/restore shared global data
-  prior to returning. (e.g. bb_common_bufsiz1 is off-limits).
+  (e.g. bb_common_bufsiz1) prior to returning.
   - getopt32() is ok to use. You do not need to save/restore option_mask32,
     it is already done by core code.
 * if you allocate memory, you can use xmalloc() only on the very first
@@ -77,3 +79,20 @@ script loops. Applets which mess with signal handlers, termios etc
 are probably not worth the effort.
 
 Any NOFORK applet is also a NOEXEC applet.
+
+
+	Relevant CONFIG options
+
+FEATURE_PREFER_APPLETS
+  BB_EXECVP(cmd, argv) will try to exec /proc/self/exe
+    if command's name matches some applet name
+  applet tables will contain NOFORK/NOEXEC bits
+  spawn_and_wait(argv) will do NOFORK/NOEXEC tricks
+
+FEATURE_SH_STANDALONE (needs FEATURE_PREFER_APPLETS=y)
+  shells will try to exec /proc/self/exe if command's name matches
+    some applet name
+  shells will do NOEXEC trick on NOEXEC applets
+
+FEATURE_SH_NOFORK (needs FEATURE_PREFER_APPLETS=y)
+  shells will do NOFORK trick on NOFORK applets
diff --git a/include/libbb.h b/include/libbb.h
index e69e279..88dceb1 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -859,6 +859,7 @@ void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const
 # define update_utmp(pid, new_type, tty_name, username, hostname) ((void)0)
 #endif
 
+
 int execable_file(const char *name) FAST_FUNC;
 char *find_execable(const char *filename, char **PATHp) FAST_FUNC;
 int exists_execable(const char *filename) FAST_FUNC;
diff --git a/shell/Config.src b/shell/Config.src
index c9c2439..e96c216 100644
--- a/shell/Config.src
+++ b/shell/Config.src
@@ -123,9 +123,9 @@ config FEATURE_SH_NOFORK
 	default n
 	depends on (HUSH || ASH) && FEATURE_PREFER_APPLETS
 	help
-	  This option causes busybox shells [currently only ash]
-	  to not execute typical fork/exec/wait sequence, but call <applet>_main
-	  directly, if possible. (Sometimes it is not possible: for example,
+	  This option causes busybox shells to not execute typical
+	  fork/exec/wait sequence, but call <applet>_main directly,
+	  if possible. (Sometimes it is not possible: for example,
 	  this is not possible in pipes).
 
 	  This will be done only for some applets (those which are marked
@@ -133,6 +133,7 @@ config FEATURE_SH_NOFORK
 
 	  This may significantly speed up some shell scripts.
 
-	  This feature is relatively new. Use with care.
+	  This feature is relatively new. Use with care. Report bugs
+	  to project mailing list.
 
 endmenu
diff --git a/shell/hush.c b/shell/hush.c
index 1709fd9..10788b8 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -6615,7 +6615,7 @@ static int checkjobs_and_fg_shell(struct pipe *fg_pipe)
  * cmd ; ...   { list } ; ...
  * cmd && ...  { list } && ...
  * cmd || ...  { list } || ...
- * If it is, then we can run cmd as a builtin, NOFORK [do we do this?],
+ * If it is, then we can run cmd as a builtin, NOFORK,
  * or (if SH_STANDALONE) an applet, and we can run the { list }
  * with run_list. If it isn't one of these, we fork and exec cmd.
  *
@@ -6797,13 +6797,12 @@ static NOINLINE int run_pipe(struct pipe *pi)
 		}
 
 		/* Expand the rest into (possibly) many strings each */
-		if (0) {}
 #if ENABLE_HUSH_BASH_COMPAT
-		else if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) {
+		if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) {
 			argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
-		}
+		} else
 #endif
-		else {
+		{
 			argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt);
 		}
 
@@ -6865,7 +6864,7 @@ static NOINLINE int run_pipe(struct pipe *pi)
 			return rcode;
 		}
 
-		if (ENABLE_FEATURE_SH_STANDALONE) {
+		if (ENABLE_FEATURE_SH_NOFORK) {
 			int n = find_applet_by_name(argv_expanded[0]);
 			if (n >= 0 && APPLET_IS_NOFORK(n)) {
 				rcode = redirect_and_varexp_helper(&new_env, &old_vars, command, squirrel, argv_expanded);
-- 
1.7.3.4



More information about the busybox-cvs mailing list