hush: make run_pipe code simpler to understand, no logic changes
function old new delta run_pipe 1641 1651 +10 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
d358b0b65d
commit
34f6b12330
69
shell/hush.c
69
shell/hush.c
@ -7599,9 +7599,8 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
|
|||||||
{
|
{
|
||||||
const struct built_in_command *x;
|
const struct built_in_command *x;
|
||||||
char **new_env;
|
char **new_env;
|
||||||
#if ENABLE_HUSH_COMMAND
|
IF_HUSH_COMMAND(char opt_vV = 0;)
|
||||||
char opt_vV = 0;
|
IF_HUSH_FUNCTIONS(const struct function *funcp;)
|
||||||
#endif
|
|
||||||
|
|
||||||
new_env = expand_assignments(argv, assignment_cnt);
|
new_env = expand_assignments(argv, assignment_cnt);
|
||||||
dump_cmd_in_x_mode(new_env);
|
dump_cmd_in_x_mode(new_env);
|
||||||
@ -7640,12 +7639,9 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
|
|||||||
|
|
||||||
#if ENABLE_HUSH_FUNCTIONS
|
#if ENABLE_HUSH_FUNCTIONS
|
||||||
/* Check if the command matches any functions (this goes before bltins) */
|
/* Check if the command matches any functions (this goes before bltins) */
|
||||||
{
|
funcp = find_function(argv[0]);
|
||||||
const struct function *funcp = find_function(argv[0]);
|
if (funcp)
|
||||||
if (funcp) {
|
|
||||||
exec_function(&nommu_save->argv_from_re_execing, funcp, argv);
|
exec_function(&nommu_save->argv_from_re_execing, funcp, argv);
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLE_HUSH_COMMAND
|
#if ENABLE_HUSH_COMMAND
|
||||||
@ -8366,22 +8362,18 @@ static NOINLINE int run_pipe(struct pipe *pi)
|
|||||||
if (!funcp)
|
if (!funcp)
|
||||||
x = find_builtin(argv_expanded[0]);
|
x = find_builtin(argv_expanded[0]);
|
||||||
if (x || funcp) {
|
if (x || funcp) {
|
||||||
if (!funcp) {
|
if (x && x->b_function == builtin_exec && argv_expanded[1] == NULL) {
|
||||||
if (x->b_function == builtin_exec && argv_expanded[1] == NULL) {
|
|
||||||
debug_printf("exec with redirects only\n");
|
debug_printf("exec with redirects only\n");
|
||||||
rcode = setup_redirects(command, NULL);
|
rcode = setup_redirects(command, NULL);
|
||||||
/* rcode=1 can be if redir file can't be opened */
|
/* rcode=1 can be if redir file can't be opened */
|
||||||
goto clean_up_and_ret1;
|
goto clean_up_and_ret1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Without bumping var nesting level, this leaks
|
/* Bump var nesting, or this will leak exported $a:
|
||||||
* exported $a:
|
|
||||||
* a=b true; env | grep ^a=
|
* a=b true; env | grep ^a=
|
||||||
*/
|
*/
|
||||||
enter_var_nest_level();
|
enter_var_nest_level();
|
||||||
rcode = redirect_and_varexp_helper(&old_vars, command, &squirrel, argv_expanded);
|
rcode = redirect_and_varexp_helper(&old_vars, command, &squirrel, argv_expanded);
|
||||||
|
|
||||||
if (rcode == 0) {
|
if (rcode == 0) {
|
||||||
if (!funcp) {
|
if (!funcp) {
|
||||||
debug_printf_exec(": builtin '%s' '%s'...\n",
|
debug_printf_exec(": builtin '%s' '%s'...\n",
|
||||||
@ -8406,10 +8398,33 @@ static NOINLINE int run_pipe(struct pipe *pi)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
clean_up_and_ret:
|
} else
|
||||||
|
if (ENABLE_FEATURE_SH_NOFORK && NUM_APPLETS > 1) {
|
||||||
|
int n = find_applet_by_name(argv_expanded[0]);
|
||||||
|
if (n < 0 || !APPLET_IS_NOFORK(n))
|
||||||
|
goto must_fork;
|
||||||
|
|
||||||
|
enter_var_nest_level();
|
||||||
|
rcode = redirect_and_varexp_helper(&old_vars, command, &squirrel, argv_expanded);
|
||||||
|
if (rcode == 0) {
|
||||||
|
debug_printf_exec(": run_nofork_applet '%s' '%s'...\n",
|
||||||
|
argv_expanded[0], argv_expanded[1]);
|
||||||
|
/*
|
||||||
|
* Note: signals (^C) can't interrupt here.
|
||||||
|
* We remember them and they will be acted upon
|
||||||
|
* after applet returns.
|
||||||
|
* This makes applets which can run for a long time
|
||||||
|
* and/or wait for user input ineligible for NOFORK:
|
||||||
|
* for example, "yes" or "rm" (rm -i waits for input).
|
||||||
|
*/
|
||||||
|
rcode = run_nofork_applet(n, argv_expanded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
leave_var_nest_level();
|
leave_var_nest_level();
|
||||||
add_vars(old_vars);
|
add_vars(old_vars);
|
||||||
restore_redirects(squirrel);
|
restore_redirects(squirrel);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try "usleep 99999999" + ^C + "echo $?"
|
* Try "usleep 99999999" + ^C + "echo $?"
|
||||||
* with FEATURE_SH_NOFORK=y.
|
* with FEATURE_SH_NOFORK=y.
|
||||||
@ -8436,30 +8451,6 @@ static NOINLINE int run_pipe(struct pipe *pi)
|
|||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ENABLE_FEATURE_SH_NOFORK && NUM_APPLETS > 1) {
|
|
||||||
int n = find_applet_by_name(argv_expanded[0]);
|
|
||||||
if (n >= 0 && APPLET_IS_NOFORK(n)) {
|
|
||||||
enter_var_nest_level();
|
|
||||||
rcode = redirect_and_varexp_helper(&old_vars, command, &squirrel, argv_expanded);
|
|
||||||
if (rcode == 0) {
|
|
||||||
debug_printf_exec(": run_nofork_applet '%s' '%s'...\n",
|
|
||||||
argv_expanded[0], argv_expanded[1]);
|
|
||||||
/*
|
|
||||||
* Note: signals (^C) can't interrupt here.
|
|
||||||
* We remember them and they will be acted upon
|
|
||||||
* after applet returns.
|
|
||||||
* This makes applets which can run for a long time
|
|
||||||
* and/or wait for user input ineligible for NOFORK:
|
|
||||||
* for example, "yes" or "rm" (rm -i waits for input).
|
|
||||||
*/
|
|
||||||
rcode = run_nofork_applet(n, argv_expanded);
|
|
||||||
}
|
|
||||||
goto clean_up_and_ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* It is neither builtin nor applet. We must fork. */
|
|
||||||
}
|
|
||||||
|
|
||||||
must_fork:
|
must_fork:
|
||||||
/* NB: argv_expanded may already be created, and that
|
/* NB: argv_expanded may already be created, and that
|
||||||
* might include `cmd` runs! Do not rerun it! We *must*
|
* might include `cmd` runs! Do not rerun it! We *must*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user