hush: use FEATURE_SH_NOFORK to enable NOFORK trick
Also expands docs Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
c71b469f5d
commit
b72baeb003
@ -44,9 +44,11 @@ NOEXEC trick is disabled for NOMMU build.
|
|||||||
NOFORK
|
NOFORK
|
||||||
|
|
||||||
NOFORK applet should work correctly if another applet simply runs
|
NOFORK applet should work correctly if another applet simply runs
|
||||||
<applet>_main(argc,argv) and then continues with its business (xargs,
|
<applet>_main(argc,argv) and then continues with its business.
|
||||||
find, shells can do it). This poses much more serious limitations
|
xargs, find, shells do it (grep for "spawn_and_wait" and
|
||||||
on what applet can/cannot do:
|
"run_nofork_applet" to find more users).
|
||||||
|
|
||||||
|
This poses much more serious limitations on what applet can do:
|
||||||
|
|
||||||
* all NOEXEC limitations apply.
|
* all NOEXEC limitations apply.
|
||||||
* do not ever exit() or exec().
|
* do not ever exit() or exec().
|
||||||
@ -56,7 +58,7 @@ on what applet can/cannot do:
|
|||||||
is taken from xfunc_error_retval.
|
is taken from xfunc_error_retval.
|
||||||
- fflush_stdout_and_exit(n) is ok to use.
|
- fflush_stdout_and_exit(n) is ok to use.
|
||||||
* do not use shared global data, or save/restore shared global data
|
* 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,
|
- getopt32() is ok to use. You do not need to save/restore option_mask32,
|
||||||
it is already done by core code.
|
it is already done by core code.
|
||||||
* if you allocate memory, you can use xmalloc() only on the very first
|
* 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.
|
are probably not worth the effort.
|
||||||
|
|
||||||
Any NOFORK applet is also a NOEXEC applet.
|
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
|
||||||
|
@ -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)
|
# define update_utmp(pid, new_type, tty_name, username, hostname) ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int execable_file(const char *name) FAST_FUNC;
|
int execable_file(const char *name) FAST_FUNC;
|
||||||
char *find_execable(const char *filename, char **PATHp) FAST_FUNC;
|
char *find_execable(const char *filename, char **PATHp) FAST_FUNC;
|
||||||
int exists_execable(const char *filename) FAST_FUNC;
|
int exists_execable(const char *filename) FAST_FUNC;
|
||||||
|
@ -123,9 +123,9 @@ config FEATURE_SH_NOFORK
|
|||||||
default n
|
default n
|
||||||
depends on (HUSH || ASH) && FEATURE_PREFER_APPLETS
|
depends on (HUSH || ASH) && FEATURE_PREFER_APPLETS
|
||||||
help
|
help
|
||||||
This option causes busybox shells [currently only ash]
|
This option causes busybox shells to not execute typical
|
||||||
to not execute typical fork/exec/wait sequence, but call <applet>_main
|
fork/exec/wait sequence, but call <applet>_main directly,
|
||||||
directly, if possible. (Sometimes it is not possible: for example,
|
if possible. (Sometimes it is not possible: for example,
|
||||||
this is not possible in pipes).
|
this is not possible in pipes).
|
||||||
|
|
||||||
This will be done only for some applets (those which are marked
|
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 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
|
endmenu
|
||||||
|
11
shell/hush.c
11
shell/hush.c
@ -6615,7 +6615,7 @@ static int checkjobs_and_fg_shell(struct pipe *fg_pipe)
|
|||||||
* cmd ; ... { list } ; ...
|
* cmd ; ... { list } ; ...
|
||||||
* cmd && ... { list } && ...
|
* 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 }
|
* 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.
|
* 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 */
|
/* Expand the rest into (possibly) many strings each */
|
||||||
if (0) {}
|
|
||||||
#if ENABLE_HUSH_BASH_COMPAT
|
#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);
|
argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt);
|
||||||
}
|
} else
|
||||||
#endif
|
#endif
|
||||||
else {
|
{
|
||||||
argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt);
|
argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6865,7 +6864,7 @@ static NOINLINE int run_pipe(struct pipe *pi)
|
|||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ENABLE_FEATURE_SH_STANDALONE) {
|
if (ENABLE_FEATURE_SH_NOFORK) {
|
||||||
int n = find_applet_by_name(argv_expanded[0]);
|
int n = find_applet_by_name(argv_expanded[0]);
|
||||||
if (n >= 0 && APPLET_IS_NOFORK(n)) {
|
if (n >= 0 && APPLET_IS_NOFORK(n)) {
|
||||||
rcode = redirect_and_varexp_helper(&new_env, &old_vars, command, squirrel, argv_expanded);
|
rcode = redirect_and_varexp_helper(&new_env, &old_vars, command, squirrel, argv_expanded);
|
||||||
|
Loading…
Reference in New Issue
Block a user