aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-02-02 18:38:57 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-02-02 18:38:57 +0100
commitb72baeb00328576df415f9a4b4f3d5f202e3be11 (patch)
treec6863cb112e6e33908e17f298d541c1b0c3aa418
parentc71b469f5daceb717e31cc9ce46b0e058e2c57b6 (diff)
downloadbusybox-w32-b72baeb00328576df415f9a4b4f3d5f202e3be11.tar.gz
busybox-w32-b72baeb00328576df415f9a4b4f3d5f202e3be11.tar.bz2
busybox-w32-b72baeb00328576df415f9a4b4f3d5f202e3be11.zip
hush: use FEATURE_SH_NOFORK to enable NOFORK trick
Also expands docs Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--docs/nofork_noexec.txt27
-rw-r--r--include/libbb.h1
-rw-r--r--shell/Config.src9
-rw-r--r--shell/hush.c11
4 files changed, 34 insertions, 14 deletions
diff --git a/docs/nofork_noexec.txt b/docs/nofork_noexec.txt
index 06c789aff..c58f5a83f 100644
--- a/docs/nofork_noexec.txt
+++ b/docs/nofork_noexec.txt
@@ -44,9 +44,11 @@ NOEXEC trick is disabled for NOMMU build.
44 NOFORK 44 NOFORK
45 45
46NOFORK applet should work correctly if another applet simply runs 46NOFORK applet should work correctly if another applet simply runs
47<applet>_main(argc,argv) and then continues with its business (xargs, 47<applet>_main(argc,argv) and then continues with its business.
48find, shells can do it). This poses much more serious limitations 48xargs, find, shells do it (grep for "spawn_and_wait" and
49on what applet can/cannot do: 49"run_nofork_applet" to find more users).
50
51This poses much more serious limitations on what applet can do:
50 52
51* all NOEXEC limitations apply. 53* all NOEXEC limitations apply.
52* do not ever exit() or exec(). 54* do not ever exit() or exec().
@@ -56,7 +58,7 @@ on what applet can/cannot do:
56 is taken from xfunc_error_retval. 58 is taken from xfunc_error_retval.
57 - fflush_stdout_and_exit(n) is ok to use. 59 - fflush_stdout_and_exit(n) is ok to use.
58* do not use shared global data, or save/restore shared global data 60* do not use shared global data, or save/restore shared global data
59 prior to returning. (e.g. bb_common_bufsiz1 is off-limits). 61 (e.g. bb_common_bufsiz1) prior to returning.
60 - getopt32() is ok to use. You do not need to save/restore option_mask32, 62 - getopt32() is ok to use. You do not need to save/restore option_mask32,
61 it is already done by core code. 63 it is already done by core code.
62* if you allocate memory, you can use xmalloc() only on the very first 64* 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
77are probably not worth the effort. 79are probably not worth the effort.
78 80
79Any NOFORK applet is also a NOEXEC applet. 81Any NOFORK applet is also a NOEXEC applet.
82
83
84 Relevant CONFIG options
85
86FEATURE_PREFER_APPLETS
87 BB_EXECVP(cmd, argv) will try to exec /proc/self/exe
88 if command's name matches some applet name
89 applet tables will contain NOFORK/NOEXEC bits
90 spawn_and_wait(argv) will do NOFORK/NOEXEC tricks
91
92FEATURE_SH_STANDALONE (needs FEATURE_PREFER_APPLETS=y)
93 shells will try to exec /proc/self/exe if command's name matches
94 some applet name
95 shells will do NOEXEC trick on NOEXEC applets
96
97FEATURE_SH_NOFORK (needs FEATURE_PREFER_APPLETS=y)
98 shells will do NOFORK trick on NOFORK applets
diff --git a/include/libbb.h b/include/libbb.h
index e69e27944..88dceb11d 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
859# define update_utmp(pid, new_type, tty_name, username, hostname) ((void)0) 859# define update_utmp(pid, new_type, tty_name, username, hostname) ((void)0)
860#endif 860#endif
861 861
862
862int execable_file(const char *name) FAST_FUNC; 863int execable_file(const char *name) FAST_FUNC;
863char *find_execable(const char *filename, char **PATHp) FAST_FUNC; 864char *find_execable(const char *filename, char **PATHp) FAST_FUNC;
864int exists_execable(const char *filename) FAST_FUNC; 865int exists_execable(const char *filename) FAST_FUNC;
diff --git a/shell/Config.src b/shell/Config.src
index c9c2439e7..e96c21620 100644
--- a/shell/Config.src
+++ b/shell/Config.src
@@ -123,9 +123,9 @@ config FEATURE_SH_NOFORK
123 default n 123 default n
124 depends on (HUSH || ASH) && FEATURE_PREFER_APPLETS 124 depends on (HUSH || ASH) && FEATURE_PREFER_APPLETS
125 help 125 help
126 This option causes busybox shells [currently only ash] 126 This option causes busybox shells to not execute typical
127 to not execute typical fork/exec/wait sequence, but call <applet>_main 127 fork/exec/wait sequence, but call <applet>_main directly,
128 directly, if possible. (Sometimes it is not possible: for example, 128 if possible. (Sometimes it is not possible: for example,
129 this is not possible in pipes). 129 this is not possible in pipes).
130 130
131 This will be done only for some applets (those which are marked 131 This will be done only for some applets (those which are marked
@@ -133,6 +133,7 @@ config FEATURE_SH_NOFORK
133 133
134 This may significantly speed up some shell scripts. 134 This may significantly speed up some shell scripts.
135 135
136 This feature is relatively new. Use with care. 136 This feature is relatively new. Use with care. Report bugs
137 to project mailing list.
137 138
138endmenu 139endmenu
diff --git a/shell/hush.c b/shell/hush.c
index 1709fd9d1..10788b8e7 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -6615,7 +6615,7 @@ static int checkjobs_and_fg_shell(struct pipe *fg_pipe)
6615 * cmd ; ... { list } ; ... 6615 * cmd ; ... { list } ; ...
6616 * cmd && ... { list } && ... 6616 * cmd && ... { list } && ...
6617 * cmd || ... { list } || ... 6617 * cmd || ... { list } || ...
6618 * If it is, then we can run cmd as a builtin, NOFORK [do we do this?], 6618 * If it is, then we can run cmd as a builtin, NOFORK,
6619 * or (if SH_STANDALONE) an applet, and we can run the { list } 6619 * or (if SH_STANDALONE) an applet, and we can run the { list }
6620 * with run_list. If it isn't one of these, we fork and exec cmd. 6620 * with run_list. If it isn't one of these, we fork and exec cmd.
6621 * 6621 *
@@ -6797,13 +6797,12 @@ static NOINLINE int run_pipe(struct pipe *pi)
6797 } 6797 }
6798 6798
6799 /* Expand the rest into (possibly) many strings each */ 6799 /* Expand the rest into (possibly) many strings each */
6800 if (0) {}
6801#if ENABLE_HUSH_BASH_COMPAT 6800#if ENABLE_HUSH_BASH_COMPAT
6802 else if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) { 6801 if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) {
6803 argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); 6802 argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
6804 } 6803 } else
6805#endif 6804#endif
6806 else { 6805 {
6807 argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt); 6806 argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt);
6808 } 6807 }
6809 6808
@@ -6865,7 +6864,7 @@ static NOINLINE int run_pipe(struct pipe *pi)
6865 return rcode; 6864 return rcode;
6866 } 6865 }
6867 6866
6868 if (ENABLE_FEATURE_SH_STANDALONE) { 6867 if (ENABLE_FEATURE_SH_NOFORK) {
6869 int n = find_applet_by_name(argv_expanded[0]); 6868 int n = find_applet_by_name(argv_expanded[0]);
6870 if (n >= 0 && APPLET_IS_NOFORK(n)) { 6869 if (n >= 0 && APPLET_IS_NOFORK(n)) {
6871 rcode = redirect_and_varexp_helper(&new_env, &old_vars, command, squirrel, argv_expanded); 6870 rcode = redirect_and_varexp_helper(&new_env, &old_vars, command, squirrel, argv_expanded);