commit bash-20051123 snapshot
[platform/upstream/bash.git] / d1a
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
3 ***************
4 *** 1,5 ****
5   /* execute_command.c -- Execute a COMMAND structure. */
6   
7 ! /* Copyright (C) 1987-2003 Free Software Foundation, Inc.
8   
9      This file is part of GNU Bash, the Bourne Again SHell.
10 --- 1,5 ----
11   /* execute_command.c -- Execute a COMMAND structure. */
12   
13 ! /* Copyright (C) 1987-2004 Free Software Foundation, Inc.
14   
15      This file is part of GNU Bash, the Bourne Again SHell.
16 ***************
17 *** 161,165 ****
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 *));
23 --- 161,165 ----
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 *));
29 ***************
30 *** 492,496 ****
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;
35   
36 --- 492,495 ----
37 ***************
38 *** 649,653 ****
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;
43   
44 --- 648,652 ----
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;
49   
50 ***************
51 *** 679,683 ****
52            when the shell is compiled without job control. */
53         if (already_making_children && pipe_out == NO_PIPE &&
54 !           last_pid != last_made_pid)
55           {
56             stop_pipeline (asynchronous, (COMMAND *)NULL);
57 --- 678,682 ----
58            when the shell is compiled without job control. */
59         if (already_making_children && pipe_out == NO_PIPE &&
60 !           last_made_pid != NO_PID)
61           {
62             stop_pipeline (asynchronous, (COMMAND *)NULL);
63 ***************
64 *** 699,710 ****
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;
74 - #endif
75           }
76         }
77 --- 698,701 ----
78 ***************
79 *** 1275,1278 ****
80 --- 1266,1274 ----
81     tcom = (command->type == cm_subshell) ? command->value.Subshell->command : command;
82   
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;
87 +   
88     /* Make sure the subshell inherits any CMD_IGNORE_RETURN flag. */
89     if ((command->flags & CMD_IGNORE_RETURN) && tcom != command)
90 ***************
91 *** 1356,1359 ****
92 --- 1352,1356 ----
93           terminate_current_pipeline ();
94           kill_current_pipeline ();
95 +         UNBLOCK_CHILD (oset);
96   #endif /* JOB_CONTROL */
97           last_command_exit_value = EXECUTION_FAILURE;
98 ***************
99 *** 1623,1628 ****
100         xtrace_print_for_command_head (for_command);
101   
102 !       /* Save this command unless it's a trap command. */
103 !       if (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))
104         {
105           FREE (the_printed_command_except_trap);
106 --- 1620,1626 ----
107         xtrace_print_for_command_head (for_command);
108   
109 !       /* Save this command unless it's a trap command and we're not running
110 !        a debug trap. */
111 !       if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
112         {
113           FREE (the_printed_command_except_trap);
114 ***************
115 *** 1639,1643 ****
116   
117         this_command_name = (char *)NULL;
118 !       v = bind_variable (identifier, list->word->word);
119         if (readonly_p (v) || noassign_p (v))
120         {
121 --- 1637,1641 ----
122   
123         this_command_name = (char *)NULL;
124 !       v = bind_variable (identifier, list->word->word, 0);
125         if (readonly_p (v) || noassign_p (v))
126         {
127 ***************
128 *** 1686,1690 ****
129           SHELL_VAR *new_value;
130   
131 !         new_value = bind_variable (identifier, value_cell(old_value));
132           new_value->attributes = old_value->attributes;
133           dispose_variable (old_value);
134 --- 1684,1688 ----
135           SHELL_VAR *new_value;
136   
137 !         new_value = bind_variable (identifier, value_cell(old_value), 0);
138           new_value->attributes = old_value->attributes;
139           dispose_variable (old_value);
140 ***************
141 *** 1732,1737 ****
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);
146   
147         r = run_debug_trap ();
148 --- 1730,1738 ----
149         command_string_index = 0;
150         print_arith_command (new);
151 !       if (signal_in_progress (DEBUG_TRAP) == 0)
152 !       {
153 !         FREE (the_printed_command_except_trap);
154 !         the_printed_command_except_trap = savestring (the_printed_command);
155 !       }
156   
157         r = run_debug_trap ();
158 ***************
159 *** 2040,2045 ****
160       xtrace_print_select_command_head (select_command);
161   
162 !   FREE (the_printed_command_except_trap);
163 !   the_printed_command_except_trap = savestring (the_printed_command);
164   
165     retval = run_debug_trap ();
166 --- 2041,2049 ----
167       xtrace_print_select_command_head (select_command);
168   
169 !   if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
170 !     {
171 !       FREE (the_printed_command_except_trap);
172 !       the_printed_command_except_trap = savestring (the_printed_command);
173 !     }
174   
175     retval = run_debug_trap ();
176 ***************
177 *** 2093,2097 ****
178         }
179   
180 !       v = bind_variable (identifier, selection);
181         if (readonly_p (v) || noassign_p (v))
182         {
183 --- 2097,2101 ----
184         }
185   
186 !       v = bind_variable (identifier, selection, 0);
187         if (readonly_p (v) || noassign_p (v))
188         {
189 ***************
190 *** 2169,2173 ****
191       xtrace_print_case_command_head (case_command);
192   
193 !   if (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))
194       {
195         FREE (the_printed_command_except_trap);
196 --- 2173,2177 ----
197       xtrace_print_case_command_head (case_command);
198   
199 !   if (signal_in_progress (DEBUG_TRAP == 0) && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
200       {
201         FREE (the_printed_command_except_trap);
202 ***************
203 *** 2186,2197 ****
204   #endif
205   
206 -   /* Posix.2 specifies that the WORD is tilde expanded. */
207 -   if (member ('~', case_command->word->word))
208 -     {
209 -       word = bash_tilde_expand (case_command->word->word, 0);
210 -       free (case_command->word->word);
211 -       case_command->word->word = word;
212 -     }
213
214     wlist = expand_word_unsplit (case_command->word, 0);
215     word = wlist ? string_list (wlist) : savestring ("");
216 --- 2190,2193 ----
217 ***************
218 *** 2211,2223 ****
219         for (list = clauses->patterns; list; list = list->next)
220         {
221 -         /* Posix.2 specifies to tilde expand each member of the pattern
222 -            list. */
223 -         if (member ('~', list->word->word))
224 -           {
225 -             pattern = bash_tilde_expand (list->word->word, 0);
226 -             free (list->word->word);
227 -             list->word->word = pattern;
228 -           }
229
230           es = expand_word_leave_quoted (list->word, 0);
231   
232 --- 2207,2210 ----
233 ***************
234 *** 2396,2401 ****
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);
239   
240     /* Run the debug trap before each arithmetic command, but do it after we
241 --- 2383,2392 ----
242     command_string_index = 0;
243     print_arith_command (arith_command->exp);
244
245 !   if (signal_in_progress (DEBUG_TRAP) == 0)
246 !     {
247 !       FREE (the_printed_command_except_trap);
248 !       the_printed_command_except_trap = savestring (the_printed_command);
249 !     }
250   
251     /* Run the debug trap before each arithmetic command, but do it after we
252 ***************
253 *** 2509,2515 ****
254         else
255   #endif /* COND_REGEXP */
256 !       result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP)
257 !                               ? EXECUTION_SUCCESS
258 !                               : EXECUTION_FAILURE;
259         if (arg1 != nullstr)
260         free (arg1);
261 --- 2500,2512 ----
262         else
263   #endif /* COND_REGEXP */
264 !       {
265 !         int oe;
266 !         oe = extended_glob;
267 !         extended_glob = 1;
268 !         result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP)
269 !                                 ? EXECUTION_SUCCESS
270 !                                 : EXECUTION_FAILURE;
271 !         extended_glob = oe;
272 !       }
273         if (arg1 != nullstr)
274         free (arg1);
275 ***************
276 *** 2547,2552 ****
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);
281   
282     /* Run the debug trap before each conditional command, but do it after we
283 --- 2544,2553 ----
284     command_string_index = 0;
285     print_cond_command (cond_command);
286
287 !   if (signal_in_progress (DEBUG_TRAP) == 0)
288 !     {
289 !       FREE (the_printed_command_except_trap);
290 !       the_printed_command_except_trap = savestring (the_printed_command);
291 !     }
292   
293     /* Run the debug trap before each conditional command, but do it after we
294 ***************
295 *** 2581,2585 ****
296     if (arg == 0)
297       arg = "";
298 !   var = bind_variable ("_", arg);
299     VUNSETATTR (var, att_exported);
300   }
301 --- 2582,2586 ----
302     if (arg == 0)
303       arg = "";
304 !   var = bind_variable ("_", arg, 0);
305     VUNSETATTR (var, att_exported);
306   }
307 ***************
308 *** 2589,2596 ****
309      supposed to take place. */
310   static int
311 ! execute_null_command (redirects, pipe_in, pipe_out, async, old_last_command_subst_pid)
312        REDIRECT *redirects;
313        int pipe_in, pipe_out, async;
314 -      pid_t old_last_command_subst_pid;
315   {
316     int r;
317 --- 2590,2596 ----
318      supposed to take place. */
319   static int
320 ! execute_null_command (redirects, pipe_in, pipe_out, async)
321        REDIRECT *redirects;
322        int pipe_in, pipe_out, async;
323   {
324     int r;
325 ***************
326 *** 2638,2642 ****
327         if (r != 0)
328         return (EXECUTION_FAILURE);
329 !       else if (old_last_command_subst_pid != last_command_subst_pid)
330         return (last_command_exit_value);
331         else
332 --- 2638,2642 ----
333         if (r != 0)
334         return (EXECUTION_FAILURE);
335 !       else if (last_command_subst_pid != NO_PID)
336         return (last_command_exit_value);
337         else
338 ***************
339 *** 2667,2672 ****
340             if (b == 0 || (b->flags & ASSIGNMENT_BUILTIN) == 0)
341               return;
342           }
343 !       w->word->flags |= (W_NOSPLIT|W_NOGLOB|W_TILDEEXP);
344         }
345   }
346 --- 2667,2674 ----
347             if (b == 0 || (b->flags & ASSIGNMENT_BUILTIN) == 0)
348               return;
349 +           else if (b && (b->flags & ASSIGNMENT_BUILTIN))
350 +             words->word->flags |= W_ASSNBLTIN;
351           }
352 !       w->word->flags |= (W_NOSPLIT|W_NOGLOB|W_TILDEEXP|W_ASSIGNARG);
353         }
354   }
355 ***************
356 *** 2684,2688 ****
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;
361     SHELL_VAR *func;
362 --- 2686,2690 ----
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;
367     SHELL_VAR *func;
368 ***************
369 *** 2700,2707 ****
370     print_simple_command (simple_command);
371   
372 !   if (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))
373       {
374         FREE (the_printed_command_except_trap);
375 !       the_printed_command_except_trap = savestring (the_printed_command);
376       }
377   
378 --- 2702,2709 ----
379     print_simple_command (simple_command);
380   
381 !   if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
382       {
383         FREE (the_printed_command_except_trap);
384 !       the_printed_command_except_trap = the_printed_command ? savestring (the_printed_command) : (char *)0;
385       }
386   
387 ***************
388 *** 2719,2723 ****
389       simple_command->words ? (simple_command->words->word->flags & W_QUOTED): 0;
390   
391 !   old_last_command_subst_pid = last_command_subst_pid;
392     old_last_async_pid = last_asynchronous_pid;
393   
394 --- 2721,2725 ----
395       simple_command->words ? (simple_command->words->word->flags & W_QUOTED): 0;
396   
397 !   last_command_subst_pid = NO_PID;
398     old_last_async_pid = last_asynchronous_pid;
399   
400 ***************
401 *** 2740,2764 ****
402     if (dofork)
403       {
404 - #if 0
405 -       /* XXX memory leak if expand_words() error causes a jump_to_top_level */
406 -       command_line = savestring (the_printed_command);
407 - #endif
408
409         /* Do this now, because execute_disk_command will do it anyway in the
410          vast majority of cases. */
411         maybe_make_export_env ();
412   
413 - #if 0
414 -       if (make_child (command_line, async) == 0)
415 - #else
416         if (make_child (savestring (the_printed_command), async) == 0)
417 - #endif
418         {
419           already_forked = 1;
420           simple_command->flags |= CMD_NO_FORK;
421   
422 !         subshell_environment = (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
423 !                                       ? (SUBSHELL_PIPE|SUBSHELL_FORK)
424 !                                       : (SUBSHELL_ASYNC|SUBSHELL_FORK);
425   
426           /* We need to do this before piping to handle some really
427 --- 2742,2759 ----
428     if (dofork)
429       {
430         /* Do this now, because execute_disk_command will do it anyway in the
431          vast majority of cases. */
432         maybe_make_export_env ();
433   
434         if (make_child (savestring (the_printed_command), async) == 0)
435         {
436           already_forked = 1;
437           simple_command->flags |= CMD_NO_FORK;
438   
439 !         subshell_environment = SUBSHELL_FORK;
440 !         if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
441 !           subshell_environment |= SUBSHELL_PIPE;
442 !         if (async)
443 !           subshell_environment |= SUBSHELL_ASYNC;
444   
445           /* We need to do this before piping to handle some really
446 ***************
447 *** 2805,2810 ****
448         result = execute_null_command (simple_command->redirects,
449                                      pipe_in, pipe_out,
450 !                                    already_forked ? 0 : async,
451 !                                    old_last_command_subst_pid);
452         if (already_forked)
453         exit (result);
454 --- 2800,2804 ----
455         result = execute_null_command (simple_command->redirects,
456                                      pipe_in, pipe_out,
457 !                                    already_forked ? 0 : async);
458         if (already_forked)
459         exit (result);
460 ***************
461 *** 3060,3064 ****
462           push_scope (VC_BLTNENV, temporary_env);
463           if (subshell == 0)
464 !           add_unwind_protect (pop_scope, "1");
465             temporary_env = (HASH_TABLE *)NULL;   
466         }
467 --- 3054,3058 ----
468           push_scope (VC_BLTNENV, temporary_env);
469           if (subshell == 0)
470 !           add_unwind_protect (pop_scope, (flags & CMD_COMMAND_BUILTIN) ? 0 : "1");
471             temporary_env = (HASH_TABLE *)NULL;   
472         }
473 ***************
474 *** 3106,3110 ****
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;
479   #endif
480 --- 3100,3104 ----
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;
485   #endif
486 ***************
487 *** 3179,3183 ****
488 --- 3173,3183 ----
489       }
490   
491 +   /* Shell functions inherit the RETURN trap if function tracing is on
492 +      globally or on individually for this function. */
493 + #if 0
494     if (return_trap && ((trace_p (var) == 0) && function_trace_mode == 0))
495 + #else
496 +   if (return_trap && (signal_in_progress (DEBUG_TRAP) || ((trace_p (var) == 0) && function_trace_mode == 0)))
497 + #endif
498       {
499         if (subshell == 0)
500 ***************
501 *** 3232,3236 ****
502   
503     if (return_val)
504 !     result = return_catch_value;
505     else
506       {
507 --- 3232,3242 ----
508   
509     if (return_val)
510 !     {
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;
516 !     }
517     else
518       {
519 ***************
520 *** 3256,3259 ****
521 --- 3262,3269 ----
522   #else
523         result = execute_command_internal (fc, 0, NO_PIPE, NO_PIPE, fds_to_close);
524
525 +       save_current = currently_executing_command;
526 +       run_return_trap ();
527 +       currently_executing_command = save_current;
528   #endif
529         showing_function_line = 0;
530 ***************
531 *** 3269,3275 ****
532     funcnest--;
533   #if defined (ARRAY_VARS)
534     array_pop (bash_source_a);
535 -   array_pop (funcname_a);
536     array_pop (bash_lineno_a);
537   #endif
538     
539 --- 3279,3292 ----
540     funcnest--;
541   #if defined (ARRAY_VARS)
542 +   /* These two variables cannot be unset, and cannot be affected by the
543 +      function. */
544     array_pop (bash_source_a);
545     array_pop (bash_lineno_a);
546
547 +   /* FUNCNAME can be unset, and so can potentially be changed by the
548 +      function. */
549 +   GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a);
550 +   if (nfv == funcname_v)
551 +     array_pop (funcname_a);
552   #endif
553