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:
Denys Vlasenko 2018-04-05 11:30:17 +02:00
parent d358b0b65d
commit 34f6b12330

View File

@ -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*