From 2d698b6e42d8dca191ac795ef5dba3bf62496eec Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 9 Apr 2010 16:13:32 -0700 Subject: Integrate bash 3.2 version This is merge of current Debian stable (Lenny) version of Bash with Vyatta changes. --- execute_cmd.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 90 insertions(+), 14 deletions(-) (limited to 'execute_cmd.c') diff --git a/execute_cmd.c b/execute_cmd.c index 9162f3e..662889a 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -1,4 +1,4 @@ -/* execute_command.c -- Execute a COMMAND structure. */ +/* execute_cmd.c -- Execute a COMMAND structure. */ /* Copyright (C) 1987-2005 Free Software Foundation, Inc. @@ -214,6 +214,8 @@ static int special_builtin_failed; report the correct line number. Kind of a hack. */ static int showing_function_line; +static int line_number_for_err_trap; + /* For catching RETURN in a function. */ int return_catch_flag; int return_catch_value; @@ -359,6 +361,7 @@ execute_command (command) unlink_fifo_list (); #endif /* PROCESS_SUBSTITUTION */ + QUIT; return (result); } @@ -501,6 +504,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, if (command == 0 || breaking || continuing || read_but_dont_execute) return (EXECUTION_SUCCESS); + QUIT; run_pending_traps (); #if 0 @@ -663,7 +667,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, if (command->flags & CMD_STDIN_REDIR) command->value.Simple->flags |= CMD_STDIN_REDIR; - line_number = command->value.Simple->line; + line_number_for_err_trap = line_number = command->value.Simple->line; exec_result = execute_simple_command (command->value.Simple, pipe_in, pipe_out, asynchronous, fds_to_close); @@ -865,6 +869,24 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, ? EXECUTION_FAILURE : EXECUTION_SUCCESS; +#if defined (DPAREN_ARITHMETIC) || defined (COND_COMMAND) + /* This is where we set PIPESTATUS from the exit status of the appropriate + compound commands (the ones that look enough like simple commands to + cause confusion). We might be able to optimize by not doing this if + subshell_environment != 0. */ + switch (command->type) + { +# if defined (DPAREN_ARITHMETIC) + case cm_arith: +# endif +# if defined (COND_COMMAND) + case cm_cond: +# endif + set_pipestatus_from_exit (exec_result); + break; + } +#endif + last_command_exit_value = exec_result; run_pending_traps (); #if 0 @@ -1187,6 +1209,10 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close) the special case of an asynchronous GROUP command where the the subshell bit is turned on down in case cm_group: below), turn off `asynchronous', so that two subshells aren't spawned. + XXX - asynchronous used to be set to 0 in this block, but that + means that setup_async_signals was never run. Now it's set to + 0 after subshell_environment is set appropriately and setup_async_signals + is run. This seems semantically correct to me. For example, ( foo ) & seems to say ``do the command `foo' in a subshell @@ -1214,19 +1240,35 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close) aliases. */ if (ois != interactive_shell) expand_aliases = 0; - asynchronous = 0; } /* Subshells are neither login nor interactive. */ login_shell = interactive = 0; - subshell_environment = user_subshell ? SUBSHELL_PAREN : SUBSHELL_ASYNC; + if (user_subshell) + subshell_environment = SUBSHELL_PAREN; + else + { + subshell_environment = 0; /* XXX */ + if (asynchronous) + subshell_environment |= SUBSHELL_ASYNC; + if (pipe_in != NO_PIPE || pipe_out != NO_PIPE) + subshell_environment |= SUBSHELL_PIPE; + } reset_terminating_signals (); /* in sig.c */ /* Cancel traps, in trap.c. */ restore_original_signals (); + + /* Make sure restore_original_signals doesn't undo the work done by + make_child to ensure that asynchronous children are immune to SIGINT + and SIGQUIT. Turn off asynchronous to make sure more subshells are + not spawned. */ if (asynchronous) - setup_async_signals (); + { + setup_async_signals (); + asynchronous = 0; + } #if defined (JOB_CONTROL) set_sigchld_handler (); @@ -1308,8 +1350,7 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close) if (function_value) return_code = return_catch_value; else - return_code = execute_command_internal - (tcom, asynchronous, NO_PIPE, NO_PIPE, fds_to_close); + return_code = execute_command_internal (tcom, asynchronous, NO_PIPE, NO_PIPE, fds_to_close); /* If we are asked to, invert the return value. */ if (invert) @@ -1629,7 +1670,11 @@ execute_for_command (for_command) /* Save this command unless it's a trap command and we're not running a debug trap. */ +#if 0 if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))) +#else + if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) +#endif { FREE (the_printed_command_except_trap); the_printed_command_except_trap = savestring (the_printed_command); @@ -2048,7 +2093,11 @@ execute_select_command (select_command) if (echo_command_at_execute) xtrace_print_select_command_head (select_command); +#if 0 if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))) +#else + if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) +#endif { FREE (the_printed_command_except_trap); the_printed_command_except_trap = savestring (the_printed_command); @@ -2180,7 +2229,11 @@ execute_case_command (case_command) if (echo_command_at_execute) xtrace_print_case_command_head (case_command); - if (signal_in_progress (DEBUG_TRAP == 0) && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))) +#if 0 + if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))) +#else + if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) +#endif { FREE (the_printed_command_except_trap); the_printed_command_except_trap = savestring (the_printed_command); @@ -2378,6 +2431,7 @@ execute_arith_command (arith_command) int expok, save_line_number, retval; intmax_t expresult; WORD_LIST *new; + char *exp; expresult = 0; @@ -2420,8 +2474,11 @@ execute_arith_command (arith_command) if (new) { - expresult = evalexp (new->word->word, &expok); + exp = new->next ? string_list (new) : new->word->word; + expresult = evalexp (exp, &expok); line_number = save_line_number; + if (exp != new->word->word) + free (exp); dispose_words (new); } else @@ -2477,6 +2534,7 @@ execute_cond_node (cond) } else if (cond->type == COND_BINARY) { + rmatch = 0; patmatch = ((cond->op->word[1] == '=') && (cond->op->word[2] == '\0') && (cond->op->word[0] == '!' || cond->op->word[0] == '=') || (cond->op->word[0] == '=' && cond->op->word[1] == '\0')); @@ -2488,7 +2546,7 @@ execute_cond_node (cond) arg1 = cond_expand_word (cond->left->op, 0); if (arg1 == 0) arg1 = nullstr; - arg2 = cond_expand_word (cond->right->op, patmatch); + arg2 = cond_expand_word (cond->right->op, patmatch||rmatch); if (arg2 == 0) arg2 = nullstr; @@ -2614,7 +2672,10 @@ execute_null_command (redirects, pipe_in, pipe_out, async) do_piping (pipe_in, pipe_out); - subshell_environment = SUBSHELL_ASYNC; + if (async) + subshell_environment |= SUBSHELL_ASYNC; + if (pipe_in != NO_PIPE || pipe_out != NO_PIPE) + subshell_environment |= SUBSHELL_PIPE; if (do_redirections (redirects, RX_ACTIVE) == 0) exit (EXECUTION_SUCCESS); @@ -2709,7 +2770,11 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close) command_string_index = 0; print_simple_command (simple_command); +#if 0 if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))) +#else + if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) +#endif { FREE (the_printed_command_except_trap); the_printed_command_except_trap = the_printed_command ? savestring (the_printed_command) : (char *)0; @@ -2983,7 +3048,7 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close) } if (command_line == 0) - command_line = savestring (the_printed_command); + command_line = savestring (the_printed_command_except_trap); execute_disk_command (words, simple_command->redirects, command_line, pipe_in, pipe_out, async, fds_to_close, @@ -3342,7 +3407,7 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var, struct fd_bitmap *fds_to_close; int flags; { - int result, r; + int result, r, funcvalue; #if defined (JOB_CONTROL) int jobs_hack; @@ -3353,7 +3418,10 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var, /* A subshell is neither a login shell nor interactive. */ login_shell = interactive = 0; - subshell_environment = SUBSHELL_ASYNC; + if (async) + subshell_environment |= SUBSHELL_ASYNC; + if (pipe_in != NO_PIPE || pipe_out != NO_PIPE) + subshell_environment |= SUBSHELL_PIPE; maybe_make_export_env (); /* XXX - is this needed? */ @@ -3387,10 +3455,18 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var, so we don't go back up to main(). */ result = setjmp (top_level); + /* Give the return builtin a place to jump to when executed in a subshell + or pipeline */ + funcvalue = 0; + if (return_catch_flag && builtin == return_builtin) + funcvalue = setjmp (return_catch); + if (result == EXITPROG) exit (last_command_exit_value); else if (result) exit (EXECUTION_FAILURE); + else if (funcvalue) + exit (return_catch_value); else { r = execute_builtin (builtin, words, flags, 1); -- cgit v1.2.3