1 *** ../bash-3.0-patched/execute_cmd.c Sun Jul 4 14:12:58 2004
2 --- execute_cmd.c Wed Dec 1 16:50:48 2004
5 /* execute_command.c -- Execute a COMMAND structure. */
7 ! /* Copyright (C) 1987-2003 Free Software Foundation, Inc.
9 This file is part of GNU Bash, the Bourne Again SHell.
11 /* execute_command.c -- Execute a COMMAND structure. */
13 ! /* Copyright (C) 1987-2004 Free Software Foundation, Inc.
15 This file is part of GNU Bash, the Bourne Again SHell.
18 static int execute_while_or_until __P((WHILE_COM *, int));
19 static int execute_if_command __P((IF_COM *));
20 ! static int execute_null_command __P((REDIRECT *, int, int, int, pid_t));
21 static void fix_assignment_words __P((WORD_LIST *));
22 static int execute_simple_command __P((SIMPLE_COM *, int, int, int, struct fd_bitmap *));
24 static int execute_while_or_until __P((WHILE_COM *, int));
25 static int execute_if_command __P((IF_COM *));
26 ! static int execute_null_command __P((REDIRECT *, int, int, int));
27 static void fix_assignment_words __P((WORD_LIST *));
28 static int execute_simple_command __P((SIMPLE_COM *, int, int, int, struct fd_bitmap *));
31 int exec_result, invert, ignore_return, was_error_trap;
32 REDIRECT *my_undo_list, *exec_undo_list;
33 - volatile pid_t last_pid;
34 volatile int save_line_number;
39 call to execute_simple_command if a longjmp occurs as the
40 result of a `return' builtin. This is true for sure with gcc. */
41 ! last_pid = last_made_pid;
42 was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
45 call to execute_simple_command if a longjmp occurs as the
46 result of a `return' builtin. This is true for sure with gcc. */
47 ! last_made_pid = NO_PID;
48 was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0;
52 when the shell is compiled without job control. */
53 if (already_making_children && pipe_out == NO_PIPE &&
54 ! last_pid != last_made_pid)
56 stop_pipeline (asynchronous, (COMMAND *)NULL);
58 when the shell is compiled without job control. */
59 if (already_making_children && pipe_out == NO_PIPE &&
60 ! last_made_pid != NO_PID)
62 stop_pipeline (asynchronous, (COMMAND *)NULL);
65 pipelines) to be waited for twice. */
66 exec_result = wait_for (last_made_pid);
67 - #if defined (RECYCLES_PIDS)
68 - /* LynxOS, for one, recycles pids very quickly -- so quickly
69 - that a new process may have the same pid as the last one
70 - created. This has been reported to fix the problem on that
71 - OS, and a similar problem on Cygwin. */
72 - if (exec_result == 0)
73 - last_made_pid = NO_PID;
81 tcom = (command->type == cm_subshell) ? command->value.Subshell->command : command;
83 + if (command->flags & CMD_TIME_PIPELINE)
84 + tcom->flags |= CMD_TIME_PIPELINE;
85 + if (command->flags & CMD_TIME_POSIX)
86 + tcom->flags |= CMD_TIME_POSIX;
88 /* Make sure the subshell inherits any CMD_IGNORE_RETURN flag. */
89 if ((command->flags & CMD_IGNORE_RETURN) && tcom != command)
93 terminate_current_pipeline ();
94 kill_current_pipeline ();
95 + UNBLOCK_CHILD (oset);
96 #endif /* JOB_CONTROL */
97 last_command_exit_value = EXECUTION_FAILURE;
100 xtrace_print_for_command_head (for_command);
102 ! /* Save this command unless it's a trap command. */
103 ! if (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))
105 FREE (the_printed_command_except_trap);
107 xtrace_print_for_command_head (for_command);
109 ! /* Save this command unless it's a trap command and we're not running
111 ! if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
113 FREE (the_printed_command_except_trap);
117 this_command_name = (char *)NULL;
118 ! v = bind_variable (identifier, list->word->word);
119 if (readonly_p (v) || noassign_p (v))
123 this_command_name = (char *)NULL;
124 ! v = bind_variable (identifier, list->word->word, 0);
125 if (readonly_p (v) || noassign_p (v))
129 SHELL_VAR *new_value;
131 ! new_value = bind_variable (identifier, value_cell(old_value));
132 new_value->attributes = old_value->attributes;
133 dispose_variable (old_value);
135 SHELL_VAR *new_value;
137 ! new_value = bind_variable (identifier, value_cell(old_value), 0);
138 new_value->attributes = old_value->attributes;
139 dispose_variable (old_value);
142 command_string_index = 0;
143 print_arith_command (new);
144 ! FREE (the_printed_command_except_trap);
145 ! the_printed_command_except_trap = savestring (the_printed_command);
147 r = run_debug_trap ();
149 command_string_index = 0;
150 print_arith_command (new);
151 ! if (signal_in_progress (DEBUG_TRAP) == 0)
153 ! FREE (the_printed_command_except_trap);
154 ! the_printed_command_except_trap = savestring (the_printed_command);
157 r = run_debug_trap ();
160 xtrace_print_select_command_head (select_command);
162 ! FREE (the_printed_command_except_trap);
163 ! the_printed_command_except_trap = savestring (the_printed_command);
165 retval = run_debug_trap ();
167 xtrace_print_select_command_head (select_command);
169 ! if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
171 ! FREE (the_printed_command_except_trap);
172 ! the_printed_command_except_trap = savestring (the_printed_command);
175 retval = run_debug_trap ();
180 ! v = bind_variable (identifier, selection);
181 if (readonly_p (v) || noassign_p (v))
186 ! v = bind_variable (identifier, selection, 0);
187 if (readonly_p (v) || noassign_p (v))
191 xtrace_print_case_command_head (case_command);
193 ! if (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))
195 FREE (the_printed_command_except_trap);
197 xtrace_print_case_command_head (case_command);
199 ! if (signal_in_progress (DEBUG_TRAP == 0) && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
201 FREE (the_printed_command_except_trap);
206 - /* Posix.2 specifies that the WORD is tilde expanded. */
207 - if (member ('~', case_command->word->word))
209 - word = bash_tilde_expand (case_command->word->word, 0);
210 - free (case_command->word->word);
211 - case_command->word->word = word;
214 wlist = expand_word_unsplit (case_command->word, 0);
215 word = wlist ? string_list (wlist) : savestring ("");
219 for (list = clauses->patterns; list; list = list->next)
221 - /* Posix.2 specifies to tilde expand each member of the pattern
223 - if (member ('~', list->word->word))
225 - pattern = bash_tilde_expand (list->word->word, 0);
226 - free (list->word->word);
227 - list->word->word = pattern;
230 es = expand_word_leave_quoted (list->word, 0);
235 command_string_index = 0;
236 print_arith_command (arith_command->exp);
237 ! FREE (the_printed_command_except_trap);
238 ! the_printed_command_except_trap = savestring (the_printed_command);
240 /* Run the debug trap before each arithmetic command, but do it after we
242 command_string_index = 0;
243 print_arith_command (arith_command->exp);
245 ! if (signal_in_progress (DEBUG_TRAP) == 0)
247 ! FREE (the_printed_command_except_trap);
248 ! the_printed_command_except_trap = savestring (the_printed_command);
251 /* Run the debug trap before each arithmetic command, but do it after we
255 #endif /* COND_REGEXP */
256 ! result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP)
257 ! ? EXECUTION_SUCCESS
258 ! : EXECUTION_FAILURE;
263 #endif /* COND_REGEXP */
266 ! oe = extended_glob;
268 ! result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP)
269 ! ? EXECUTION_SUCCESS
270 ! : EXECUTION_FAILURE;
271 ! extended_glob = oe;
277 command_string_index = 0;
278 print_cond_command (cond_command);
279 ! FREE (the_printed_command_except_trap);
280 ! the_printed_command_except_trap = savestring (the_printed_command);
282 /* Run the debug trap before each conditional command, but do it after we
284 command_string_index = 0;
285 print_cond_command (cond_command);
287 ! if (signal_in_progress (DEBUG_TRAP) == 0)
289 ! FREE (the_printed_command_except_trap);
290 ! the_printed_command_except_trap = savestring (the_printed_command);
293 /* Run the debug trap before each conditional command, but do it after we
298 ! var = bind_variable ("_", arg);
299 VUNSETATTR (var, att_exported);
304 ! var = bind_variable ("_", arg, 0);
305 VUNSETATTR (var, att_exported);
309 supposed to take place. */
311 ! execute_null_command (redirects, pipe_in, pipe_out, async, old_last_command_subst_pid)
313 int pipe_in, pipe_out, async;
314 - pid_t old_last_command_subst_pid;
318 supposed to take place. */
320 ! execute_null_command (redirects, pipe_in, pipe_out, async)
322 int pipe_in, pipe_out, async;
328 return (EXECUTION_FAILURE);
329 ! else if (old_last_command_subst_pid != last_command_subst_pid)
330 return (last_command_exit_value);
334 return (EXECUTION_FAILURE);
335 ! else if (last_command_subst_pid != NO_PID)
336 return (last_command_exit_value);
340 if (b == 0 || (b->flags & ASSIGNMENT_BUILTIN) == 0)
343 ! w->word->flags |= (W_NOSPLIT|W_NOGLOB|W_TILDEEXP);
347 if (b == 0 || (b->flags & ASSIGNMENT_BUILTIN) == 0)
349 + else if (b && (b->flags & ASSIGNMENT_BUILTIN))
350 + words->word->flags |= W_ASSNBLTIN;
352 ! w->word->flags |= (W_NOSPLIT|W_NOGLOB|W_TILDEEXP|W_ASSIGNARG);
357 char *command_line, *lastarg, *temp;
358 int first_word_quoted, result, builtin_is_special, already_forked, dofork;
359 ! pid_t old_last_command_subst_pid, old_last_async_pid;
360 sh_builtin_func_t *builtin;
363 char *command_line, *lastarg, *temp;
364 int first_word_quoted, result, builtin_is_special, already_forked, dofork;
365 ! pid_t old_last_async_pid;
366 sh_builtin_func_t *builtin;
370 print_simple_command (simple_command);
372 ! if (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))
374 FREE (the_printed_command_except_trap);
375 ! the_printed_command_except_trap = savestring (the_printed_command);
379 print_simple_command (simple_command);
381 ! if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
383 FREE (the_printed_command_except_trap);
384 ! the_printed_command_except_trap = the_printed_command ? savestring (the_printed_command) : (char *)0;
389 simple_command->words ? (simple_command->words->word->flags & W_QUOTED): 0;
391 ! old_last_command_subst_pid = last_command_subst_pid;
392 old_last_async_pid = last_asynchronous_pid;
395 simple_command->words ? (simple_command->words->word->flags & W_QUOTED): 0;
397 ! last_command_subst_pid = NO_PID;
398 old_last_async_pid = last_asynchronous_pid;
405 - /* XXX memory leak if expand_words() error causes a jump_to_top_level */
406 - command_line = savestring (the_printed_command);
409 /* Do this now, because execute_disk_command will do it anyway in the
410 vast majority of cases. */
411 maybe_make_export_env ();
414 - if (make_child (command_line, async) == 0)
416 if (make_child (savestring (the_printed_command), async) == 0)
420 simple_command->flags |= CMD_NO_FORK;
422 ! subshell_environment = (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
423 ! ? (SUBSHELL_PIPE|SUBSHELL_FORK)
424 ! : (SUBSHELL_ASYNC|SUBSHELL_FORK);
426 /* We need to do this before piping to handle some really
430 /* Do this now, because execute_disk_command will do it anyway in the
431 vast majority of cases. */
432 maybe_make_export_env ();
434 if (make_child (savestring (the_printed_command), async) == 0)
437 simple_command->flags |= CMD_NO_FORK;
439 ! subshell_environment = SUBSHELL_FORK;
440 ! if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
441 ! subshell_environment |= SUBSHELL_PIPE;
443 ! subshell_environment |= SUBSHELL_ASYNC;
445 /* We need to do this before piping to handle some really
448 result = execute_null_command (simple_command->redirects,
450 ! already_forked ? 0 : async,
451 ! old_last_command_subst_pid);
455 result = execute_null_command (simple_command->redirects,
457 ! already_forked ? 0 : async);
462 push_scope (VC_BLTNENV, temporary_env);
464 ! add_unwind_protect (pop_scope, "1");
465 temporary_env = (HASH_TABLE *)NULL;
468 push_scope (VC_BLTNENV, temporary_env);
470 ! add_unwind_protect (pop_scope, (flags & CMD_COMMAND_BUILTIN) ? 0 : "1");
471 temporary_env = (HASH_TABLE *)NULL;
475 char *debug_trap, *error_trap, *return_trap;
476 #if defined (ARRAY_VARS)
477 ! SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v;
478 ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
481 char *debug_trap, *error_trap, *return_trap;
482 #if defined (ARRAY_VARS)
483 ! SHELL_VAR *funcname_v, *nfv, *bash_source_v, *bash_lineno_v;
484 ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
491 + /* Shell functions inherit the RETURN trap if function tracing is on
492 + globally or on individually for this function. */
494 if (return_trap && ((trace_p (var) == 0) && function_trace_mode == 0))
496 + if (return_trap && (signal_in_progress (DEBUG_TRAP) || ((trace_p (var) == 0) && function_trace_mode == 0)))
504 ! result = return_catch_value;
511 ! result = return_catch_value;
512 ! /* Run the RETURN trap in the function's context. */
513 ! save_current = currently_executing_command;
514 ! run_return_trap ();
515 ! currently_executing_command = save_current;
523 result = execute_command_internal (fc, 0, NO_PIPE, NO_PIPE, fds_to_close);
525 + save_current = currently_executing_command;
526 + run_return_trap ();
527 + currently_executing_command = save_current;
529 showing_function_line = 0;
533 #if defined (ARRAY_VARS)
534 array_pop (bash_source_a);
535 - array_pop (funcname_a);
536 array_pop (bash_lineno_a);
541 #if defined (ARRAY_VARS)
542 + /* These two variables cannot be unset, and cannot be affected by the
544 array_pop (bash_source_a);
545 array_pop (bash_lineno_a);
547 + /* FUNCNAME can be unset, and so can potentially be changed by the
549 + GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
550 + if (nfv == funcname_v)
551 + array_pop (funcname_a);