diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-02-02 18:38:57 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-02-02 18:38:57 +0100 |
commit | b72baeb00328576df415f9a4b4f3d5f202e3be11 (patch) | |
tree | c6863cb112e6e33908e17f298d541c1b0c3aa418 | |
parent | c71b469f5daceb717e31cc9ce46b0e058e2c57b6 (diff) | |
download | busybox-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.txt | 27 | ||||
-rw-r--r-- | include/libbb.h | 1 | ||||
-rw-r--r-- | shell/Config.src | 9 | ||||
-rw-r--r-- | shell/hush.c | 11 |
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 | ||
46 | NOFORK applet should work correctly if another applet simply runs | 46 | NOFORK 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. |
48 | find, shells can do it). This poses much more serious limitations | 48 | xargs, find, shells do it (grep for "spawn_and_wait" and |
49 | on what applet can/cannot do: | 49 | "run_nofork_applet" to find more users). |
50 | |||
51 | This 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 | |||
77 | are probably not worth the effort. | 79 | are probably not worth the effort. |
78 | 80 | ||
79 | Any NOFORK applet is also a NOEXEC applet. | 81 | Any NOFORK applet is also a NOEXEC applet. |
82 | |||
83 | |||
84 | Relevant CONFIG options | ||
85 | |||
86 | FEATURE_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 | |||
92 | FEATURE_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 | |||
97 | FEATURE_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 | |||
862 | int execable_file(const char *name) FAST_FUNC; | 863 | int execable_file(const char *name) FAST_FUNC; |
863 | char *find_execable(const char *filename, char **PATHp) FAST_FUNC; | 864 | char *find_execable(const char *filename, char **PATHp) FAST_FUNC; |
864 | int exists_execable(const char *filename) FAST_FUNC; | 865 | int 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 | ||
138 | endmenu | 139 | endmenu |
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); |