source: patches/bash-4.0-branch_update-4.patch @ e6b4db2

clfs-1.2clfs-2.1clfs-3.0.0-systemdclfs-3.0.0-sysvinitsystemdsysvinit
Last change on this file since e6b4db2 was e6b4db2, checked in by Jim Gifford <clfs@…>, 15 years ago

Updated Bash Branch Update Patch to -4

  • Property mode set to 100644
File size: 25.0 KB
RevLine 
[c822ddc]1Submitted By: Jim Gifford (jim at cross-lfs dot org)
[e6b4db2]2Date: 04-09-2009
[c822ddc]3Initial Package Version: 4.0
4Origin: Upstream
5Upstream Status: Applied
[e6b4db2]6Description: Contains all upstream patches up to 4.0-017
[c822ddc]7
8diff -Naur bash-4.0.orig/arrayfunc.c bash-4.0/arrayfunc.c
9--- bash-4.0.orig/arrayfunc.c   2009-01-04 11:32:21.000000000 -0800
[e6b4db2]10+++ bash-4.0/arrayfunc.c        2009-04-09 22:09:24.500045537 -0700
[c822ddc]11@@ -604,64 +604,7 @@
12     }
13 }
14 
15-/* This function assumes s[i] == '['; returns with s[ret] == ']' if
16-   an array subscript is correctly parsed. */
17-int
18-skipsubscript (s, i)
19-     const char *s;
20-     int i;
21-{
22-  int count, c;
23-#if defined (HANDLE_MULTIBYTE)
24-  mbstate_t state, state_bak;
25-  size_t slength, mblength;
26-#endif
27-
28-#if defined (HANDLE_MULTIBYTE)
29-  memset (&state, '\0', sizeof (mbstate_t));
30-  slength = strlen (s + i);
31-#endif
32
33-  count = 1;
34-  while (count)
35-    {
36-      /* Advance one (possibly multibyte) character in S starting at I. */
37-#if defined (HANDLE_MULTIBYTE)
38-      if (MB_CUR_MAX > 1)
39-       {
40-         state_bak = state;
41-         mblength = mbrlen (s + i, slength, &state);
42-
43-         if (MB_INVALIDCH (mblength))
44-           {
45-             state = state_bak;
46-             i++;
47-             slength--;
48-           }
49-         else if (MB_NULLWCH (mblength))
50-           return i;
51-         else
52-           {
53-             i += mblength;
54-             slength -= mblength;
55-           }
56-       }
57-      else
58-#endif
59-      ++i;
60-
61-      c = s[i];
62-
63-      if (c == 0)
64-       break;
65-      else if (c == '[')
66-       count++;
67-      else if (c == ']')
68-       count--;
69-    }
70-
71-  return i;
72-}
73+/* skipsubscript moved to subst.c to use private functions. 2009/02/24. */
74 
75 /* This function is called with SUB pointing to just after the beginning
76    `[' of an array subscript and removes the array element to which SUB
77diff -Naur bash-4.0.orig/builtins/declare.def bash-4.0/builtins/declare.def
78--- bash-4.0.orig/builtins/declare.def  2009-01-04 11:32:22.000000000 -0800
[e6b4db2]79+++ bash-4.0/builtins/declare.def       2009-04-09 22:09:21.747868696 -0700
[973b90d5]80@@ -295,6 +295,13 @@
[c822ddc]81       subscript_start = (char *)NULL;
82       if (t = strchr (name, '['))      /* ] */
83        {
84+         /* If offset != 0 we have already validated any array reference */
85+         if (offset == 0 && valid_array_reference (name) == 0)
86+           {
87+             sh_invalidid (name);
88+             assign_error++;
89+             NEXT_VARIABLE ();
90+           }
91          subscript_start = t;
92          *t = '\0';
93          making_array_special = 1;
[973b90d5]94@@ -484,7 +491,7 @@
[c822ddc]95            }
96          /* declare -a name[[n]] or declare name[n] makes name an indexed
97             array variable. */
98-         else if ((making_array_special || (flags_on & att_array)) && array_p (var) == 0)
99+         else if ((making_array_special || (flags_on & att_array)) && array_p (var) == 0 && assoc_p (var) == 0)
100            var = convert_var_to_array (var);
101 #endif /* ARRAY_VARS */
102 
103diff -Naur bash-4.0.orig/builtins/exit.def bash-4.0/builtins/exit.def
104--- bash-4.0.orig/builtins/exit.def     2009-01-04 11:32:22.000000000 -0800
[e6b4db2]105+++ bash-4.0/builtins/exit.def  2009-04-09 22:09:20.423784047 -0700
[c822ddc]106@@ -113,7 +113,7 @@
107       for (i = stopmsg = 0; i < js.j_jobslots; i++)
108        if (jobs[i] && STOPPED (i))
109          stopmsg = JSTOPPED;
110-       else if (check_jobs_at_exit && stopmsg == 0 && RUNNING (i))
111+       else if (check_jobs_at_exit && stopmsg == 0 && jobs[i] && RUNNING (i))
112          stopmsg = JRUNNING;
113 
114       if (stopmsg == JSTOPPED)
[e6b4db2]115diff -Naur bash-4.0.orig/builtins/fc.def bash-4.0/builtins/fc.def
116--- bash-4.0.orig/builtins/fc.def       2009-01-04 11:32:22.000000000 -0800
117+++ bash-4.0/builtins/fc.def    2009-04-09 22:09:34.484684732 -0700
118@@ -88,6 +88,7 @@
119 extern int current_command_line_count;
120 extern int literal_history;
121 extern int posixly_correct;
122+extern int subshell_environment, interactive_shell;
123 
124 extern int unlink __P((const char *));
125 
126@@ -172,7 +173,7 @@
127   register int i;
128   register char *sep;
129   int numbering, reverse, listing, execute;
130-  int histbeg, histend, last_hist, retval, opt;
131+  int histbeg, histend, last_hist, retval, opt, rh;
132   FILE *stream;
133   REPL *rlist, *rl;
134   char *ename, *command, *newcom, *fcedit;
135@@ -275,6 +276,8 @@
136 
137       fprintf (stderr, "%s\n", command);
138       fc_replhist (command);   /* replace `fc -s' with command */
139+      /* Posix says that the re-executed commands should be entered into the
140+        history. */
141       return (parse_and_execute (command, "fc", SEVAL_NOHIST));
142     }
143 
144@@ -293,7 +296,12 @@
145      line was actually added (HISTIGNORE may have caused it to not be),
146      so we check hist_last_line_added. */
147 
148-  last_hist = i - remember_on_history - hist_last_line_added;
149+  /* Even though command substitution through parse_and_execute turns off
150+     remember_on_history, command substitution in a shell when set -o history
151+     has been enabled (interactive or not) should use it in the last_hist
152+     calculation as if it were on. */
153+  rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
154+  last_hist = i - rh - hist_last_line_added;
155 
156   if (list)
157     {
158@@ -456,7 +464,7 @@
159      char *command;
160      HIST_ENTRY **hlist;
161 {
162-  int sign, n, clen;
163+  int sign, n, clen, rh;
164   register int i, j;
165   register char *s;
166 
167@@ -472,7 +480,12 @@
168      line was actually added (HISTIGNORE may have caused it to not be),
169      so we check hist_last_line_added.  This needs to agree with the
170      calculation of last_hist in fc_builtin above. */
171-  i -= remember_on_history + hist_last_line_added;
172+  /* Even though command substitution through parse_and_execute turns off
173+     remember_on_history, command substitution in a shell when set -o history
174+     has been enabled (interactive or not) should use it in the last_hist
175+     calculation as if it were on. */
176+  rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
177+  i -= rh + hist_last_line_added;
178 
179   /* No specification defaults to most recent command. */
180   if (command == NULL)
[7a39f29]181diff -Naur bash-4.0.orig/builtins/read.def bash-4.0/builtins/read.def
182--- bash-4.0.orig/builtins/read.def     2009-01-15 20:11:21.000000000 -0800
[e6b4db2]183+++ bash-4.0/builtins/read.def  2009-04-09 22:09:27.380229641 -0700
[7a39f29]184@@ -369,14 +369,14 @@
185       code = setjmp (alrmbuf);
186       if (code)
187        {
188-#if 0
189+         /* Tricky.  The top of the unwind-protect stack is the free of
190+            input_string.  We want to run all the rest and use input_string,
191+            so we have to remove it from the stack. */
192+         remove_unwind_protect ();
193          run_unwind_frame ("read_builtin");
194-         return (EXECUTION_FAILURE);
195-#else
196          input_string[i] = '\0';       /* make sure it's terminated */
197-         retval = 128+SIGALRM;;
198+         retval = 128+SIGALRM;
199          goto assign_vars;
200-#endif
201        }
202       old_alrm = set_signal_handler (SIGALRM, sigalrm);
203       add_unwind_protect (reset_alarm, (char *)NULL);
[e6b4db2]204diff -Naur bash-4.0.orig/execute_cmd.c bash-4.0/execute_cmd.c
205--- bash-4.0.orig/execute_cmd.c 2009-02-13 13:41:41.000000000 -0800
206+++ bash-4.0/execute_cmd.c      2009-04-09 22:09:37.908905992 -0700
207@@ -568,6 +568,7 @@
208 
209       /* Fork a subshell, turn off the subshell bit, turn off job
210         control and call execute_command () on the command again. */
211+      line_number_for_err_trap = line_number;
212       paren_pid = make_child (savestring (make_command_string (command)),
213                              asynchronous);
214       if (paren_pid == 0)
215@@ -610,7 +611,10 @@
216              if (user_subshell && was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
217                {
218                  last_command_exit_value = exec_result;
219+                 save_line_number = line_number;
220+                 line_number = line_number_for_err_trap;
221                  run_error_trap ();
222+                 line_number = save_line_number;
223                }
224 
225              if (user_subshell && ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
226@@ -766,7 +770,9 @@
227       if (was_error_trap && ignore_return == 0 && invert == 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS)
228        {
229          last_command_exit_value = exec_result;
230+         line_number = line_number_for_err_trap;
231          run_error_trap ();
232+         line_number = save_line_number;
233        }
234 
235       if (ignore_return == 0 && invert == 0 &&
236@@ -2105,6 +2111,7 @@
237   REDIRECT *rp;
238   COMMAND *tc, *second;
239   int ignore_return, exec_result, was_error_trap, invert;
240+  volatile int save_line_number;
241 
242   ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
243 
244@@ -2174,12 +2181,16 @@
245       invert = (command->flags & CMD_INVERT_RETURN) != 0;
246       ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
247 
248+      line_number_for_err_trap = line_number;
249       exec_result = execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close);
250 
251       if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
252        {
253          last_command_exit_value = exec_result;
254+         save_line_number = line_number;
255+         line_number = line_number_for_err_trap;
256          run_error_trap ();
257+         line_number = save_line_number;
258        }
259 
260       if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
261@@ -2930,7 +2941,7 @@
262                  retval = execute_command (clauses->action);
263                }
264              while ((clauses->flags & CASEPAT_FALLTHROUGH) && (clauses = clauses->next));
265-             if ((clauses->flags & CASEPAT_TESTNEXT) == 0)
266+             if (clauses == 0 || (clauses->flags & CASEPAT_TESTNEXT) == 0)
267                EXIT_CASE ();
268              else
269                break;
[c822ddc]270diff -Naur bash-4.0.orig/parse.y bash-4.0/parse.y
271--- bash-4.0.orig/parse.y       2009-01-08 05:29:12.000000000 -0800
[e6b4db2]272+++ bash-4.0/parse.y    2009-04-09 22:09:39.212989803 -0700
273@@ -1122,7 +1122,7 @@
274                          REDIRECTEE rd;
275                          REDIRECT *r;
276 
277-                         tc = $1;
278+                         tc = $1->type == cm_simple ? (COMMAND *)$1->value.Simple : $1;
279                          rd.dest = 1;
280                          r = make_redirection (2, r_duplicating_output, rd);
281                          if (tc->redirects)
[c822ddc]282@@ -1615,10 +1615,11 @@
283 {
284   int *ret;
285 
286-  ret = (int *)xmalloc (3 * sizeof (int));
287+  ret = (int *)xmalloc (4 * sizeof (int));
288   ret[0] = last_read_token;
289   ret[1] = token_before_that;
290   ret[2] = two_tokens_ago;
291+  ret[3] = current_token;
292   return ret;
293 }
294 
295@@ -1631,6 +1632,7 @@
296   last_read_token = ts[0];
297   token_before_that = ts[1];
298   two_tokens_ago = ts[2];
299+  current_token = ts[3];
300 }
301 
302 /*
[e6b4db2]303@@ -1877,7 +1879,7 @@
304     prompt_again ();
305   ret = read_a_line (remove_quoted_newline);
306 #if defined (HISTORY)
307-  if (remember_on_history && (parser_state & PST_HEREDOC))
308+  if (ret && remember_on_history && (parser_state & PST_HEREDOC))
309     {
310       /* To make adding the the here-document body right, we need to rely
311         on history_delimiting_chars() returning \n for the first line of
[c822ddc]312@@ -2668,6 +2670,7 @@
313   FREE (word_desc_to_read);
314   word_desc_to_read = (WORD_DESC *)NULL;
315 
316+  current_token = '\n';                /* XXX */
317   last_read_token = '\n';
318   token_to_read = '\n';
319 }
320@@ -2915,6 +2918,7 @@
321 #define P_DQUOTE       0x04
322 #define P_COMMAND      0x08    /* parsing a command, so look for comments */
323 #define P_BACKQUOTE    0x10    /* parsing a backquoted command substitution */
324+#define P_ARRAYSUB     0x20    /* parsing a [...] array subscript for assignment */
325 
326 /* Lexical state while parsing a grouping construct or $(...). */
327 #define LEX_WASDOL     0x001
[973b90d5]328@@ -2927,6 +2931,7 @@
329 #define LEX_INHEREDOC  0x080
330 #define LEX_HEREDELIM  0x100           /* reading here-doc delimiter */
331 #define LEX_STRIPDOC   0x200           /* <<- strip tabs from here doc delim */
332+#define LEX_INWORD     0x400
333 
334 #define COMSUB_META(ch)                ((ch) == ';' || (ch) == '&' || (ch) == '|')
335 
336@@ -3129,6 +3134,8 @@
[c822ddc]337              APPEND_NESTRET ();
338              FREE (nestret);
339            }
340+         else if ((flags & P_ARRAYSUB) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))      /* ) } ] */
341+           goto parse_dollar_word;
342        }
343       /* Parse an old-style command substitution within double quotes as a
344         single word. */
[973b90d5]345@@ -3145,6 +3152,7 @@
[c822ddc]346       else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))    /* ) } ] */
347        /* check for $(), $[], or ${} inside quoted string. */
348        {
349+parse_dollar_word:
350          if (open == ch)       /* undo previous increment */
351            count--;
352          if (ch == '(')                /* ) */
[973b90d5]353@@ -3179,7 +3187,7 @@
354      int open, close;
355      int *lenp, flags;
356 {
357-  int count, ch, peekc, tflags, lex_rwlen, lex_firstind;
358+  int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
359   int nestlen, ttranslen, start_lineno;
360   char *ret, *nestret, *ttrans, *heredelim;
361   int retind, retsize, rflags, hdlen;
362@@ -3200,7 +3208,7 @@
363   retind = 0;
364 
365   start_lineno = line_number;
366-  lex_rwlen = 0;
367+  lex_rwlen = lex_wlen = 0;
368 
369   heredelim = 0;
370   lex_firstind = -1;
371@@ -3267,6 +3275,46 @@
372          continue;
[c822ddc]373        }
374 
[973b90d5]375+      if (tflags & LEX_PASSNEXT)               /* last char was backslash */
376+       {
377+/*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
378+         tflags &= ~LEX_PASSNEXT;
379+         if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
380+           {
381+             if (retind > 0)
382+               retind--;       /* swallow previously-added backslash */
383+             continue;
384+           }
385+
386+         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
387+         if MBTEST(ch == CTLESC || ch == CTLNUL)
388+           ret[retind++] = CTLESC;
389+         ret[retind++] = ch;
390+         continue;
391+       }
392+
393+      /* If this is a shell break character, we are not in a word.  If not,
394+        we either start or continue a word. */
395+      if MBTEST(shellbreak (ch))
396+       {
397+         tflags &= ~LEX_INWORD;
398+/*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
399+       }
400+      else
401+       {
402+         if (tflags & LEX_INWORD)
403+           {
404+             lex_wlen++;
405+/*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
406+           }         
407+         else
408+           {
409+/*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
410+             tflags |= LEX_INWORD;
411+             lex_wlen = 0;
412+           }
413+       }
414+
415       /* Skip whitespace */
416       if MBTEST(shellblank (ch) && lex_rwlen == 0)
417         {
418@@ -3364,9 +3412,21 @@
419 }             
420              tflags &= ~LEX_RESWDOK;
421            }
422-         else if (shellbreak (ch) == 0)
423+         else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
424+           ;   /* don't modify LEX_RESWDOK if we're starting a comment */
425+         else if MBTEST((tflags & LEX_INCASE) && ch != '\n')
426+           /* If we can read a reserved word and we're in case, we're at the
427+              point where we can read a new pattern list or an esac.  We
428+              handle the esac case above.  If we read a newline, we want to
429+              leave LEX_RESWDOK alone.  If we read anything else, we want to
430+              turn off LEX_RESWDOK, since we're going to read a pattern list. */
431 {
432-             tflags &= ~LEX_RESWDOK;
433+           tflags &= ~LEX_RESWDOK;
434+/*itrace("parse_comsub:%d: lex_incase == 1 found `%c', lex_reswordok -> 0", line_number, ch);*/
435+}
436+         else if MBTEST(shellbreak (ch) == 0)
437+{
438+           tflags &= ~LEX_RESWDOK;
439 /*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
440 }
441        }
442@@ -3394,36 +3454,23 @@
[c822ddc]443                }
444              else
445                shell_ungetc (peekc);
446-             tflags |= LEX_HEREDELIM;
447-             lex_firstind = -1;
448+             if (peekc != '<')
449+               {
450+                 tflags |= LEX_HEREDELIM;
451+                 lex_firstind = -1;
452+               }
453              continue;
454            }
455          else
[973b90d5]456-           ch = peekc;         /* fall through and continue XXX - this skips comments if peekc == '#' */
457+           ch = peekc;         /* fall through and continue XXX */
458        }
459-      /* Not exactly right yet, should handle shell metacharacters, too.  If
460-        any changes are made to this test, make analogous changes to subst.c:
461-        extract_delimited_string(). */
462-      else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
463+      else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
464+{
465+/*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
466        tflags |= LEX_INCOMMENT;
467+}
468 
469-      if (tflags & LEX_PASSNEXT)               /* last char was backslash */
470-       {
471-         tflags &= ~LEX_PASSNEXT;
472-         if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
473-           {
474-             if (retind > 0)
475-               retind--;       /* swallow previously-added backslash */
476-             continue;
477-           }
478-
479-         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
480-         if MBTEST(ch == CTLESC || ch == CTLNUL)
481-           ret[retind++] = CTLESC;
482-         ret[retind++] = ch;
483-         continue;
484-       }
485-      else if MBTEST(ch == CTLESC || ch == CTLNUL)     /* special shell escapes */
486+      if MBTEST(ch == CTLESC || ch == CTLNUL)  /* special shell escapes */
487        {
488          RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
489          ret[retind++] = CTLESC;
490@@ -4248,7 +4295,7 @@
[c822ddc]491                     ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
492                      (token_index == 0 && (parser_state&PST_COMPASSIGN))))
493         {
494-         ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
495+         ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
496          if (ttok == &matched_pair_error)
497            return -1;          /* Bail immediately. */
498          RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
[973b90d5]499@@ -4449,6 +4496,7 @@
[c822ddc]500     case '}':          /* XXX */
501     case AND_AND:
502     case BANG:
503+    case BAR_AND:
504     case DO:
505     case DONE:
506     case ELIF:
[973b90d5]507diff -Naur bash-4.0.orig/patchlevel.h bash-4.0/patchlevel.h
508--- bash-4.0.orig/patchlevel.h  2009-01-04 11:32:40.000000000 -0800
[e6b4db2]509+++ bash-4.0/patchlevel.h       2009-04-09 22:09:39.212989803 -0700
[973b90d5]510@@ -25,6 +25,6 @@
511    regexp `^#define[   ]*PATCHLEVEL', since that's what support/mkversion.sh
512    looks for to find the patch level (for the sccs version string). */
513 
514-#define PATCHLEVEL 0
[e6b4db2]515+#define PATCHLEVEL 17
[973b90d5]516 
517 #endif /* _PATCHLEVEL_H_ */
[c822ddc]518diff -Naur bash-4.0.orig/pcomplete.c bash-4.0/pcomplete.c
519--- bash-4.0.orig/pcomplete.c   2009-02-01 14:12:31.000000000 -0800
[e6b4db2]520+++ bash-4.0/pcomplete.c        2009-04-09 22:09:17.783614750 -0700
[c822ddc]521@@ -1032,6 +1032,7 @@
522   cmdlist = build_arg_list (funcname, text, lwords, cw);
523 
524   pps = &ps;
525+  save_parser_state (pps);
526   begin_unwind_frame ("gen-shell-function-matches");
527   add_unwind_protect (restore_parser_state, (char *)pps);
528   add_unwind_protect (dispose_words, (char *)cmdlist);
[e6b4db2]529diff -Naur bash-4.0.orig/sig.c bash-4.0/sig.c
530--- bash-4.0.orig/sig.c 2009-01-04 11:32:41.000000000 -0800
531+++ bash-4.0/sig.c      2009-04-09 22:09:36.612821343 -0700
532@@ -448,6 +448,48 @@
533 termsig_sighandler (sig)
534      int sig;
535 {
536+  /* If we get called twice with the same signal before handling it,
537+     terminate right away. */
538+  if (
539+#ifdef SIGHUP
540+    sig != SIGHUP &&
541+#endif
542+#ifdef SIGINT
543+    sig != SIGINT &&
544+#endif
545+#ifdef SIGDANGER
546+    sig != SIGDANGER &&
547+#endif
548+#ifdef SIGPIPE
549+    sig != SIGPIPE &&
550+#endif
551+#ifdef SIGALRM
552+    sig != SIGALRM &&
553+#endif
554+#ifdef SIGTERM
555+    sig != SIGTERM &&
556+#endif
557+#ifdef SIGXCPU
558+    sig != SIGXCPU &&
559+#endif
560+#ifdef SIGXFSZ
561+    sig != SIGXFSZ &&
562+#endif
563+#ifdef SIGVTALRM
564+    sig != SIGVTALRM &&
565+#endif
566+#ifdef SIGLOST
567+    sig != SIGLOST &&
568+#endif
569+#ifdef SIGUSR1
570+    sig != SIGUSR1 &&
571+#endif
572+#ifdef SIGUSR2
573+   sig != SIGUSR2 &&
574+#endif
575+   sig == terminating_signal)
576+    terminate_immediately = 1;
577+
578   terminating_signal = sig;
579 
580   /* XXX - should this also trigger when interrupt_immediately is set? */
[c822ddc]581diff -Naur bash-4.0.orig/subst.c bash-4.0/subst.c
582--- bash-4.0.orig/subst.c       2009-01-28 11:34:12.000000000 -0800
[e6b4db2]583+++ bash-4.0/subst.c    2009-04-09 22:09:33.024593378 -0700
584@@ -85,6 +85,7 @@
585 
586 /* Flags for the `pflags' argument to param_expand() */
587 #define PF_NOCOMSUB    0x01    /* Do not perform command substitution */
588+#define PF_IGNUNBOUND  0x02    /* ignore unbound vars even if -u set */
589 
590 /* These defs make it easier to use the editor. */
591 #define LBRACE         '{'
592@@ -222,6 +223,7 @@
[c822ddc]593 static int skip_double_quoted __P((char *, size_t, int));
594 static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
595 static char *extract_dollar_brace_string __P((char *, int *, int, int));
596+static int skip_matched_pair __P((const char *, int, int, int, int));
597 
598 static char *pos_params __P((char *, int, int, int));
599 
[e6b4db2]600@@ -262,7 +264,7 @@
601 static int chk_atstar __P((char *, int, int *, int *));
602 static int chk_arithsub __P((const char *, int));
603 
604-static WORD_DESC *parameter_brace_expand_word __P((char *, int, int));
605+static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int));
606 static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
607 static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
608 static void parameter_brace_expand_error __P((char *, char *));
609@@ -1374,6 +1376,107 @@
[c822ddc]610 
611 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
612 
613+/* This function assumes s[i] == open; returns with s[ret] == close; used to
614+   parse array subscripts.  FLAGS currently unused. */
615+static int
616+skip_matched_pair (string, start, open, close, flags)
617+     const char *string;
618+     int start, open, close, flags;
619+{
620+  int i, pass_next, backq, si, c, count;
621+  size_t slen;
622+  char *temp, *ss;
623+  DECLARE_MBSTATE;
624+
625+  slen = strlen (string + start) + start;
626+  no_longjmp_on_fatal_error = 1;
627+
628+  i = start + 1;               /* skip over leading bracket */
629+  count = 1;
630+  pass_next = backq = 0;
631+  ss = (char *)string;
632+  while (c = string[i])
633+    {
634+      if (pass_next)
635+       {
636+         pass_next = 0;
637+         if (c == 0)
638+           CQ_RETURN(i);
639+         ADVANCE_CHAR (string, slen, i);
640+         continue;
641+       }
642+      else if (c == '\\')
643+       {
644+         pass_next = 1;
645+         i++;
646+         continue;
647+       }
648+      else if (backq)
649+       {
650+         if (c == '`')
651+           backq = 0;
652+         ADVANCE_CHAR (string, slen, i);
653+         continue;
654+       }
655+      else if (c == '`')
656+       {
657+         backq = 1;
658+         i++;
659+         continue;
660+       }
661+      else if (c == open)
662+       {
663+         count++;
664+         i++;
665+         continue;
666+       }
667+      else if (c == close)
668+       {
669+         count--;
670+         if (count == 0)
671+           break;
672+         i++;
673+         continue;
674+       }
675+      else if (c == '\'' || c == '"')
676+       {
677+         i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
678+                         : skip_double_quoted (ss, slen, ++i);
679+         /* no increment, the skip functions increment past the closing quote. */
680+       }
681+      else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
682+       {
683+         si = i + 2;
684+         if (string[si] == '\0')
685+           CQ_RETURN(si);
686+
687+         if (string[i+1] == LPAREN)
688+           temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
689+         else
690+           temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
691+         i = si;
692+         if (string[i] == '\0')        /* don't increment i past EOS in loop */
693+           break;
694+         i++;
695+         continue;
696+       }
697+      else
698+       ADVANCE_CHAR (string, slen, i);
699+    }
700+
701+  CQ_RETURN(i);
702+}
703+
704+#if defined (ARRAY_VARS)
705+int
706+skipsubscript (string, start)
707+     const char *string;
708+     int start;
709+{
710+  return (skip_matched_pair (string, start, '[', ']', 0));
711+}
712+#endif
713+
714 /* Skip characters in STRING until we find a character in DELIMS, and return
715    the index of that character.  START is the index into string at which we
716    begin.  This is similar in spirit to strpbrk, but it returns an index into
[e6b4db2]717@@ -5093,9 +5196,9 @@
718    the shell, e.g., "@", "$", "*", etc.  QUOTED, if non-zero, means that
719    NAME was found inside of a double-quoted expression. */
720 static WORD_DESC *
721-parameter_brace_expand_word (name, var_is_special, quoted)
722+parameter_brace_expand_word (name, var_is_special, quoted, pflags)
723      char *name;
724-     int var_is_special, quoted;
725+     int var_is_special, quoted, pflags;
726 {
727   WORD_DESC *ret;
728   char *temp, *tt;
729@@ -5127,7 +5230,7 @@
730       strcpy (tt + 1, name);
731 
732       ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
733-                         (int *)NULL, (int *)NULL, 0);
734+                         (int *)NULL, (int *)NULL, pflags);
735       free (tt);
736     }
737 #if defined (ARRAY_VARS)
738@@ -5188,7 +5291,7 @@
739   char *temp, *t;
740   WORD_DESC *w;
741 
742-  w = parameter_brace_expand_word (name, var_is_special, quoted);
743+  w = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
744   t = w->word;
745   /* Have to dequote here if necessary */
746   if (t)
747@@ -5205,7 +5308,7 @@
748   if (t == 0)
749     return (WORD_DESC *)NULL;
750 
751-  w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted);
752+  w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted, 0);
753   free (t);
754 
755   return w;
756@@ -6556,7 +6659,7 @@
757   if (want_indir)
758     tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
759   else
760-    tdesc = parameter_brace_expand_word (name, var_is_special, quoted);
761+    tdesc = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
762 
763   if (tdesc)
764     {
765@@ -6887,7 +6990,7 @@
766     case '*':          /* `$*' */
767       list = list_rest_of_args ();
768 
769-      if (list == 0 && unbound_vars_is_error)
770+      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
771        {
772          uerror[0] = '$';
773          uerror[1] = '*';
774@@ -6949,7 +7052,7 @@
775     case '@':          /* `$@' */
776       list = list_rest_of_args ();
777 
778-      if (list == 0 && unbound_vars_is_error)
779+      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
780        {
781          uerror[0] = '$';
782          uerror[1] = '@';
783diff -Naur bash-4.0.orig/trap.c bash-4.0/trap.c
784--- bash-4.0.orig/trap.c        2009-01-16 14:07:53.000000000 -0800
785+++ bash-4.0/trap.c     2009-04-09 22:09:37.908905992 -0700
786@@ -755,7 +755,7 @@
787        }
788 
789       flags = SEVAL_NONINT|SEVAL_NOHIST;
790-      if (sig != DEBUG_TRAP && sig != RETURN_TRAP)
791+      if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP)
792        flags |= SEVAL_RESETLINE;
793       if (function_code == 0)
794        parse_and_execute (trap_command, tag, flags);
Note: See TracBrowser for help on using the repository browser.