source: patches/bash-4.0-branch_update-6.patch @ 8e00734

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

Updated Bash Branch Update Patch

  • Property mode set to 100644
File size: 39.5 KB
RevLine 
[c822ddc]1Submitted By: Jim Gifford (jim at cross-lfs dot org)
[8e00734]2Date: 07-22-2009
[c822ddc]3Initial Package Version: 4.0
4Origin: Upstream
5Upstream Status: Applied
[8e00734]6Description: Contains all upstream patches up to 4.0-028
[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
[8e00734]10+++ bash-4.0/arrayfunc.c        2009-07-22 15:31:16.000000000 -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
[8e00734]79+++ bash-4.0/builtins/declare.def       2009-07-22 15:31:12.000000000 -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
[8e00734]105+++ bash-4.0/builtins/exit.def  2009-07-22 15:31:11.000000000 -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
[8e00734]117+++ bash-4.0/builtins/fc.def    2009-07-22 15:31:26.000000000 -0700
[e6b4db2]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
[8e00734]183+++ bash-4.0/builtins/read.def  2009-07-22 15:31:19.000000000 -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);
[8e00734]204diff -Naur bash-4.0.orig/doc/bash.1 bash-4.0/doc/bash.1
205--- bash-4.0.orig/doc/bash.1    2009-02-18 12:13:56.000000000 -0800
206+++ bash-4.0/doc/bash.1 2009-07-22 15:31:48.000000000 -0700
207@@ -8257,9 +8257,10 @@
208 Exit after reading and executing one command.
209 .TP 8
210 .B \-u
211-Treat unset variables as an error when performing
212+Treat unset variables and parameters other than the special
213+parameters "@" and "*" as an error when performing
214 parameter expansion.  If expansion is attempted on an
215-unset variable, the shell prints an error message, and,
216+unset variable or parameter, the shell prints an error message, and,
217 if not interactive, exits with a non-zero status.
218 .TP 8
219 .B \-v
220diff -Naur bash-4.0.orig/doc/bashref.texi bash-4.0/doc/bashref.texi
221--- bash-4.0.orig/doc/bashref.texi      2009-02-18 12:14:43.000000000 -0800
222+++ bash-4.0/doc/bashref.texi   2009-07-22 15:31:48.000000000 -0700
223@@ -4138,7 +4138,8 @@
224 Exit after reading and executing one command.
225 
226 @item -u
227-Treat unset variables as an error when performing parameter expansion.
228+Treat unset variables and parameters other than the special parameters
229+@samp{@@} or @samp{*} as an error when performing parameter expansion.
230 An error message will be written to the standard error, and a non-interactive
231 shell will exit.
232 
[e6b4db2]233diff -Naur bash-4.0.orig/execute_cmd.c bash-4.0/execute_cmd.c
234--- bash-4.0.orig/execute_cmd.c 2009-02-13 13:41:41.000000000 -0800
[8e00734]235+++ bash-4.0/execute_cmd.c      2009-07-22 15:31:29.000000000 -0700
[e6b4db2]236@@ -568,6 +568,7 @@
237 
238       /* Fork a subshell, turn off the subshell bit, turn off job
239         control and call execute_command () on the command again. */
240+      line_number_for_err_trap = line_number;
241       paren_pid = make_child (savestring (make_command_string (command)),
242                              asynchronous);
243       if (paren_pid == 0)
244@@ -610,7 +611,10 @@
245              if (user_subshell && was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
246                {
247                  last_command_exit_value = exec_result;
248+                 save_line_number = line_number;
249+                 line_number = line_number_for_err_trap;
250                  run_error_trap ();
251+                 line_number = save_line_number;
252                }
253 
254              if (user_subshell && ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
255@@ -766,7 +770,9 @@
256       if (was_error_trap && ignore_return == 0 && invert == 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS)
257        {
258          last_command_exit_value = exec_result;
259+         line_number = line_number_for_err_trap;
260          run_error_trap ();
261+         line_number = save_line_number;
262        }
263 
264       if (ignore_return == 0 && invert == 0 &&
265@@ -2105,6 +2111,7 @@
266   REDIRECT *rp;
267   COMMAND *tc, *second;
268   int ignore_return, exec_result, was_error_trap, invert;
269+  volatile int save_line_number;
270 
271   ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
272 
273@@ -2174,12 +2181,16 @@
274       invert = (command->flags & CMD_INVERT_RETURN) != 0;
275       ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
276 
277+      line_number_for_err_trap = line_number;
278       exec_result = execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close);
279 
280       if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
281        {
282          last_command_exit_value = exec_result;
283+         save_line_number = line_number;
284+         line_number = line_number_for_err_trap;
285          run_error_trap ();
286+         line_number = save_line_number;
287        }
288 
289       if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
290@@ -2930,7 +2941,7 @@
291                  retval = execute_command (clauses->action);
292                }
293              while ((clauses->flags & CASEPAT_FALLTHROUGH) && (clauses = clauses->next));
294-             if ((clauses->flags & CASEPAT_TESTNEXT) == 0)
295+             if (clauses == 0 || (clauses->flags & CASEPAT_TESTNEXT) == 0)
296                EXIT_CASE ();
297              else
298                break;
[8e00734]299diff -Naur bash-4.0.orig/externs.h bash-4.0/externs.h
300--- bash-4.0.orig/externs.h     2009-01-18 15:29:29.000000000 -0800
301+++ bash-4.0/externs.h  2009-07-22 15:31:45.000000000 -0700
302@@ -192,6 +192,8 @@
303 extern char *fmtumax __P((uintmax_t, int, char *, size_t, int));
304 
305 /* Declarations for functions defined in lib/sh/fpurge.c */
306+
307+#if defined NEED_FPURGE_DECL
308 #if !HAVE_DECL_FPURGE
309 
310 #if HAVE_FPURGE
311@@ -200,7 +202,7 @@
312 extern int fpurge __P((FILE *stream));
313 
314 #endif /* HAVE_DECL_FPURGE */
315-
316+#endif /* NEED_FPURGE_DECL */
317 
318 /* Declarations for functions defined in lib/sh/getcwd.c */
319 #if !defined (HAVE_GETCWD)
[140d857]320diff -Naur bash-4.0.orig/jobs.c bash-4.0/jobs.c
321--- bash-4.0.orig/jobs.c        2009-01-29 14:09:49.000000000 -0800
[8e00734]322+++ bash-4.0/jobs.c     2009-07-22 15:31:34.000000000 -0700
[140d857]323@@ -442,7 +442,7 @@
324   old_pipeline = the_pipeline;
325   the_pipeline = saved_pipeline;
326   already_making_children = saved_already_making_children;
327-  if (discard)
328+  if (discard && old_pipeline)
329     discard_pipeline (old_pipeline);
330 }
331 
332@@ -4202,4 +4202,23 @@
333   sh_closepipe (pgrp_pipe);
334 }
335 
336+void
337+save_pgrp_pipe (p, clear)
338+     int *p;
339+     int clear;
340+{
341+  p[0] = pgrp_pipe[0];
342+  p[1] = pgrp_pipe[1];
343+  if (clear)
344+    pgrp_pipe[0] = pgrp_pipe[1] = -1;
345+}
346+
347+void
348+restore_pgrp_pipe (p)
349+     int *p;
350+{
351+  pgrp_pipe[0] = p[0];
352+  pgrp_pipe[1] = p[1];
353+}
354+
355 #endif /* PGRP_PIPE */
356diff -Naur bash-4.0.orig/jobs.h bash-4.0/jobs.h
357--- bash-4.0.orig/jobs.h        2009-01-04 11:32:29.000000000 -0800
[8e00734]358+++ bash-4.0/jobs.h     2009-07-22 15:31:34.000000000 -0700
[140d857]359@@ -235,6 +235,8 @@
360 extern void init_job_stats __P((void));
361 
362 extern void close_pgrp_pipe __P((void));
363+extern void save_pgrp_pipe __P((int *, int));
364+extern void restore_pgrp_pipe __P((int *));
365 
366 #if defined (JOB_CONTROL)
367 extern int job_control;
368diff -Naur bash-4.0.orig/lib/glob/glob.c bash-4.0/lib/glob/glob.c
369--- bash-4.0.orig/lib/glob/glob.c       2009-01-04 11:32:30.000000000 -0800
[8e00734]370+++ bash-4.0/lib/glob/glob.c    2009-07-22 15:31:43.000000000 -0700
[140d857]371@@ -356,7 +356,7 @@
372        *np = 0;
373       if (ep)
374         *ep = 0;
375-      if (r)
376+      if (r && r != &glob_error_return)
377        free (r);
378       return (struct globval *)0;
379     }
[8e00734]380@@ -665,7 +665,9 @@
[140d857]381       (void) closedir (d);
382     }
383 
384-  /* compat: if GX_ALLDIRS, add the passed directory also */
[8e00734]385+  /* compat: if GX_ADDCURDIR, add the passed directory also.  Add an empty
386+     directory name as a placeholder if GX_NULLDIR (in which case the passed
387+     directory name is "."). */
388   if (add_current)
[140d857]389     {
390       sdlen = strlen (dir);
[8e00734]391@@ -942,7 +944,12 @@
[140d857]392              char **array;
393              register unsigned int l;
394 
395-             array = glob_dir_to_array (directories[i], temp_results, flags);
396+             /* If we're expanding **, we don't need to glue the directory
397+                name to the results; we've already done it in glob_vector */
398+             if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
399+               array = temp_results;
400+             else
401+               array = glob_dir_to_array (directories[i], temp_results, flags);
402              l = 0;
403              while (array[l] != NULL)
404                ++l;
[8e00734]405@@ -959,7 +966,8 @@
[140d857]406              result[result_size - 1] = NULL;
407 
408              /* Note that the elements of ARRAY are not freed.  */
409-             free ((char *) array);
410+             if (array != temp_results)
411+               free ((char *) array);
412            }
413        }
414       /* Free the directories.  */
[8e00734]415@@ -1003,11 +1011,24 @@
416 
417       /* Just return what glob_vector () returns appended to the
418         directory name. */
419+      /* If flags & GX_ALLDIRS, we're called recursively */
420       dflags = flags & ~GX_MARKDIRS;
421       if (directory_len == 0)
422        dflags |= GX_NULLDIR;
423       if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
424-       dflags |= GX_ALLDIRS|GX_ADDCURDIR;
425+       {
426+         dflags |= GX_ALLDIRS|GX_ADDCURDIR;
427+#if 0
428+         /* If we want all directories (dflags & GX_ALLDIRS) and we're not
429+            being called recursively as something like `echo **/*.o'
430+            ((flags & GX_ALLDIRS) == 0), we want to prevent glob_vector from
431+            adding a null directory name to the front of the temp_results
432+            array.  We turn off ADDCURDIR if not called recursively and
433+            dlen == 0 */
434+#endif
435+         if (directory_len == 0 && (flags & GX_ALLDIRS) == 0)
436+           dflags &= ~GX_ADDCURDIR;
437+       }
438       temp_results = glob_vector (filename,
439                                  (directory_len == 0 ? "." : directory_name),
440                                  dflags);
[140d857]441diff -Naur bash-4.0.orig/lib/readline/display.c bash-4.0/lib/readline/display.c
442--- bash-4.0.orig/lib/readline/display.c        2009-01-04 11:32:32.000000000 -0800
[8e00734]443+++ bash-4.0/lib/readline/display.c     2009-07-22 15:31:46.000000000 -0700
[140d857]444@@ -512,6 +512,7 @@
445   /* Block keyboard interrupts because this function manipulates global
446      data structures. */
447   _rl_block_sigint (); 
448+  RL_SETSTATE (RL_STATE_REDISPLAYING);
449 
450   if (!rl_display_prompt)
451     rl_display_prompt = "";
[8e00734]452@@ -1188,9 +1189,11 @@
453       if (t < out)
454        line[t - 1] = '>';
455 
456-      if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
457+      if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin)
458        {
459          forced_display = 0;
460+         o_cpos = _rl_last_c_pos;
461+         cpos_adjusted = 0;
462          update_line (&visible_line[last_lmargin],
463                       &invisible_line[lmargin],
464                       0,
465@@ -1198,6 +1201,13 @@
466                       _rl_screenwidth + (lmargin ? 0 : wrap_offset),
467                       0);
468 
469+         if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
470+             cpos_adjusted == 0 &&
471+             _rl_last_c_pos != o_cpos &&
472+             _rl_last_c_pos > wrap_offset &&
473+             o_cpos < prompt_last_invisible)
474+               _rl_last_c_pos -= prompt_invis_chars_first_line;        /* XXX - was wrap_offset */
475+
476          /* If the visible new line is shorter than the old, but the number
477             of invisible characters is greater, and we are at the end of
478             the new line, we need to clear to eol. */
479@@ -1236,6 +1246,7 @@
[140d857]480       visible_wrap_offset = wrap_offset;
481   }
482 
483+  RL_UNSETSTATE (RL_STATE_REDISPLAYING);
484   _rl_release_sigint ();
485 }
486 
[8e00734]487@@ -1772,7 +1783,7 @@
[140d857]488             space_to_eol will insert too many spaces.  XXX - maybe we should
489             adjust col_lendiff based on the difference between _rl_last_c_pos
490             and _rl_screenwidth */
491-         if (col_lendiff && (_rl_last_c_pos < _rl_screenwidth))
492+         if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
493 #endif
494            {     
495              if (_rl_term_autowrap && current_line < inv_botlin)
[8e00734]496@@ -1892,6 +1903,10 @@
[140d857]497 
498   woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
499   cpos = _rl_last_c_pos;
500+
501+  if (cpos == 0 && cpos == new)
502+    return;
503+
504 #if defined (HANDLE_MULTIBYTE)
505   /* If we have multibyte characters, NEW is indexed by the buffer point in
506      a multibyte string, but _rl_last_c_pos is the display position.  In
[8e00734]507@@ -1905,9 +1920,9 @@
[140d857]508         prompt string, since they're both buffer indices and DPOS is a
509         desired display position. */
510       if ((new > prompt_last_invisible) ||             /* XXX - don't use woff here */
511-         (prompt_physical_chars > _rl_screenwidth &&
512+         (prompt_physical_chars >= _rl_screenwidth &&
513           _rl_last_v_pos == prompt_last_screen_line &&
514-          wrap_offset >= woff &&
515+          wrap_offset >= woff && dpos >= woff &&
516           new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset)))
517           /* XXX last comparison might need to be >= */
518        {
519diff -Naur bash-4.0.orig/lib/readline/readline.h bash-4.0/lib/readline/readline.h
520--- bash-4.0.orig/lib/readline/readline.h       2009-01-04 11:32:33.000000000 -0800
[8e00734]521+++ bash-4.0/lib/readline/readline.h    2009-07-22 15:31:36.000000000 -0700
[140d857]522@@ -814,8 +814,9 @@
523 #define RL_STATE_VIMOTION      0x100000        /* reading vi motion arg */
524 #define RL_STATE_MULTIKEY      0x200000        /* reading multiple-key command */
525 #define RL_STATE_VICMDONCE     0x400000        /* entered vi command mode at least once */
526+#define RL_STATE_REDISPLAYING  0x800000        /* updating terminal display */
527 
528-#define RL_STATE_DONE          0x800000        /* done; accepted line */
529+#define RL_STATE_DONE          0x1000000       /* done; accepted line */
530 
531 #define RL_SETSTATE(x)         (rl_readline_state |= (x))
532 #define RL_UNSETSTATE(x)       (rl_readline_state &= ~(x))
533diff -Naur bash-4.0.orig/lib/readline/terminal.c bash-4.0/lib/readline/terminal.c
534--- bash-4.0.orig/lib/readline/terminal.c       2009-01-04 11:32:34.000000000 -0800
[8e00734]535+++ bash-4.0/lib/readline/terminal.c    2009-07-22 15:31:36.000000000 -0700
[140d857]536@@ -355,7 +355,7 @@
537       _rl_get_screen_size (fileno (rl_instream), 1);
538       if (CUSTOM_REDISPLAY_FUNC ())
539        rl_forced_update_display ();
540-      else
541+      else if (RL_ISSTATE(RL_STATE_REDISPLAYING) == 0)
542        _rl_redisplay_after_sigwinch ();
543     }
544 }
545diff -Naur bash-4.0.orig/lib/sh/winsize.c bash-4.0/lib/sh/winsize.c
546--- bash-4.0.orig/lib/sh/winsize.c      2008-08-12 10:53:51.000000000 -0700
[8e00734]547+++ bash-4.0/lib/sh/winsize.c   2009-07-22 15:31:33.000000000 -0700
[140d857]548@@ -30,16 +30,29 @@
549 
550 #include <sys/ioctl.h>
551 
552-#if !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
553-/* For struct winsize on SCO */
554-/*   sys/ptem.h has winsize but needs mblk_t from sys/stream.h */
555-#  if defined (HAVE_SYS_PTEM_H) && defined (TIOCGWINSZ) && defined (SIGWINCH)
556-#    if defined (HAVE_SYS_STREAM_H)
557-#      include <sys/stream.h>
558-#    endif
559+/* Try to find the definitions of `struct winsize' and TIOGCWINSZ */
560+
561+#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
562+#  include <sys/ioctl.h>
563+#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
564+
565+#if defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
566+#  include <termios.h>
567+#endif /* STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */
568+
569+/* Not in either of the standard places, look around. */
570+#if !defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
571+#  if defined (HAVE_SYS_STREAM_H)
572+#    include <sys/stream.h>
573+#  endif /* HAVE_SYS_STREAM_H */
574+#  if defined (HAVE_SYS_PTEM_H) /* SVR4.2, at least, has it here */
575 #    include <sys/ptem.h>
576-#  endif /* HAVE_SYS_PTEM_H && TIOCGWINSZ && SIGWINCH */
577-#endif /* !STRUCT_WINSIZE_IN_SYS_IOCTL */
578+#    define _IO_PTEM_H          /* work around SVR4.2 1.1.4 bug */
579+#  endif /* HAVE_SYS_PTEM_H */
580+#  if defined (HAVE_SYS_PTE_H)  /* ??? */
581+#    include <sys/pte.h>
582+#  endif /* HAVE_SYS_PTE_H */
583+#endif /* !STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */
584 
585 #include <stdio.h>
586 
[c822ddc]587diff -Naur bash-4.0.orig/parse.y bash-4.0/parse.y
588--- bash-4.0.orig/parse.y       2009-01-08 05:29:12.000000000 -0800
[8e00734]589+++ bash-4.0/parse.y    2009-07-22 15:31:39.000000000 -0700
[e6b4db2]590@@ -1122,7 +1122,7 @@
591                          REDIRECTEE rd;
592                          REDIRECT *r;
593 
594-                         tc = $1;
595+                         tc = $1->type == cm_simple ? (COMMAND *)$1->value.Simple : $1;
596                          rd.dest = 1;
597                          r = make_redirection (2, r_duplicating_output, rd);
598                          if (tc->redirects)
[c822ddc]599@@ -1615,10 +1615,11 @@
600 {
601   int *ret;
602 
603-  ret = (int *)xmalloc (3 * sizeof (int));
604+  ret = (int *)xmalloc (4 * sizeof (int));
605   ret[0] = last_read_token;
606   ret[1] = token_before_that;
607   ret[2] = two_tokens_ago;
608+  ret[3] = current_token;
609   return ret;
610 }
611 
612@@ -1631,6 +1632,7 @@
613   last_read_token = ts[0];
614   token_before_that = ts[1];
615   two_tokens_ago = ts[2];
616+  current_token = ts[3];
617 }
618 
619 /*
[e6b4db2]620@@ -1877,7 +1879,7 @@
621     prompt_again ();
622   ret = read_a_line (remove_quoted_newline);
623 #if defined (HISTORY)
624-  if (remember_on_history && (parser_state & PST_HEREDOC))
625+  if (ret && remember_on_history && (parser_state & PST_HEREDOC))
626     {
627       /* To make adding the the here-document body right, we need to rely
628         on history_delimiting_chars() returning \n for the first line of
[c822ddc]629@@ -2668,6 +2670,7 @@
630   FREE (word_desc_to_read);
631   word_desc_to_read = (WORD_DESC *)NULL;
632 
633+  current_token = '\n';                /* XXX */
634   last_read_token = '\n';
635   token_to_read = '\n';
636 }
637@@ -2915,6 +2918,7 @@
638 #define P_DQUOTE       0x04
639 #define P_COMMAND      0x08    /* parsing a command, so look for comments */
640 #define P_BACKQUOTE    0x10    /* parsing a backquoted command substitution */
641+#define P_ARRAYSUB     0x20    /* parsing a [...] array subscript for assignment */
642 
643 /* Lexical state while parsing a grouping construct or $(...). */
644 #define LEX_WASDOL     0x001
[973b90d5]645@@ -2927,6 +2931,7 @@
646 #define LEX_INHEREDOC  0x080
647 #define LEX_HEREDELIM  0x100           /* reading here-doc delimiter */
648 #define LEX_STRIPDOC   0x200           /* <<- strip tabs from here doc delim */
649+#define LEX_INWORD     0x400
650 
651 #define COMSUB_META(ch)                ((ch) == ';' || (ch) == '&' || (ch) == '|')
652 
653@@ -3129,6 +3134,8 @@
[c822ddc]654              APPEND_NESTRET ();
655              FREE (nestret);
656            }
657+         else if ((flags & P_ARRAYSUB) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))      /* ) } ] */
658+           goto parse_dollar_word;
659        }
660       /* Parse an old-style command substitution within double quotes as a
661         single word. */
[973b90d5]662@@ -3145,6 +3152,7 @@
[c822ddc]663       else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))    /* ) } ] */
664        /* check for $(), $[], or ${} inside quoted string. */
665        {
666+parse_dollar_word:
667          if (open == ch)       /* undo previous increment */
668            count--;
669          if (ch == '(')                /* ) */
[973b90d5]670@@ -3179,7 +3187,7 @@
671      int open, close;
672      int *lenp, flags;
673 {
674-  int count, ch, peekc, tflags, lex_rwlen, lex_firstind;
675+  int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
676   int nestlen, ttranslen, start_lineno;
677   char *ret, *nestret, *ttrans, *heredelim;
678   int retind, retsize, rflags, hdlen;
679@@ -3200,7 +3208,7 @@
680   retind = 0;
681 
682   start_lineno = line_number;
683-  lex_rwlen = 0;
684+  lex_rwlen = lex_wlen = 0;
685 
686   heredelim = 0;
687   lex_firstind = -1;
688@@ -3267,6 +3275,46 @@
689          continue;
[c822ddc]690        }
691 
[973b90d5]692+      if (tflags & LEX_PASSNEXT)               /* last char was backslash */
693+       {
694+/*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
695+         tflags &= ~LEX_PASSNEXT;
696+         if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
697+           {
698+             if (retind > 0)
699+               retind--;       /* swallow previously-added backslash */
700+             continue;
701+           }
702+
703+         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
704+         if MBTEST(ch == CTLESC || ch == CTLNUL)
705+           ret[retind++] = CTLESC;
706+         ret[retind++] = ch;
707+         continue;
708+       }
709+
710+      /* If this is a shell break character, we are not in a word.  If not,
711+        we either start or continue a word. */
712+      if MBTEST(shellbreak (ch))
713+       {
714+         tflags &= ~LEX_INWORD;
715+/*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
716+       }
717+      else
718+       {
719+         if (tflags & LEX_INWORD)
720+           {
721+             lex_wlen++;
722+/*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
723+           }         
724+         else
725+           {
726+/*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
727+             tflags |= LEX_INWORD;
728+             lex_wlen = 0;
729+           }
730+       }
731+
732       /* Skip whitespace */
733       if MBTEST(shellblank (ch) && lex_rwlen == 0)
734         {
[140d857]735@@ -3306,7 +3354,7 @@
736        }
737 
738       /* Meta-characters that can introduce a reserved word.  Not perfect yet. */
739-      if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && shellmeta(ch))
740+      if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && (shellmeta(ch) || ch == '\n'))
741        {
742          /* Add this character. */
743          RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
[973b90d5]744@@ -3364,9 +3412,21 @@
745 }             
746              tflags &= ~LEX_RESWDOK;
747            }
748-         else if (shellbreak (ch) == 0)
749+         else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
750+           ;   /* don't modify LEX_RESWDOK if we're starting a comment */
751+         else if MBTEST((tflags & LEX_INCASE) && ch != '\n')
752+           /* If we can read a reserved word and we're in case, we're at the
753+              point where we can read a new pattern list or an esac.  We
754+              handle the esac case above.  If we read a newline, we want to
755+              leave LEX_RESWDOK alone.  If we read anything else, we want to
756+              turn off LEX_RESWDOK, since we're going to read a pattern list. */
757 {
758-             tflags &= ~LEX_RESWDOK;
759+           tflags &= ~LEX_RESWDOK;
760+/*itrace("parse_comsub:%d: lex_incase == 1 found `%c', lex_reswordok -> 0", line_number, ch);*/
761+}
762+         else if MBTEST(shellbreak (ch) == 0)
763+{
764+           tflags &= ~LEX_RESWDOK;
765 /*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
766 }
767        }
768@@ -3394,36 +3454,23 @@
[c822ddc]769                }
770              else
771                shell_ungetc (peekc);
772-             tflags |= LEX_HEREDELIM;
773-             lex_firstind = -1;
774+             if (peekc != '<')
775+               {
776+                 tflags |= LEX_HEREDELIM;
777+                 lex_firstind = -1;
778+               }
779              continue;
780            }
781          else
[973b90d5]782-           ch = peekc;         /* fall through and continue XXX - this skips comments if peekc == '#' */
783+           ch = peekc;         /* fall through and continue XXX */
784        }
785-      /* Not exactly right yet, should handle shell metacharacters, too.  If
786-        any changes are made to this test, make analogous changes to subst.c:
787-        extract_delimited_string(). */
788-      else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
789+      else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
790+{
791+/*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
792        tflags |= LEX_INCOMMENT;
793+}
794 
795-      if (tflags & LEX_PASSNEXT)               /* last char was backslash */
796-       {
797-         tflags &= ~LEX_PASSNEXT;
798-         if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
799-           {
800-             if (retind > 0)
801-               retind--;       /* swallow previously-added backslash */
802-             continue;
803-           }
804-
805-         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
806-         if MBTEST(ch == CTLESC || ch == CTLNUL)
807-           ret[retind++] = CTLESC;
808-         ret[retind++] = ch;
809-         continue;
810-       }
811-      else if MBTEST(ch == CTLESC || ch == CTLNUL)     /* special shell escapes */
812+      if MBTEST(ch == CTLESC || ch == CTLNUL)  /* special shell escapes */
813        {
814          RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
815          ret[retind++] = CTLESC;
816@@ -4248,7 +4295,7 @@
[c822ddc]817                     ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
818                      (token_index == 0 && (parser_state&PST_COMPASSIGN))))
819         {
820-         ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
821+         ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
822          if (ttok == &matched_pair_error)
823            return -1;          /* Bail immediately. */
824          RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
[973b90d5]825@@ -4449,6 +4496,7 @@
[c822ddc]826     case '}':          /* XXX */
827     case AND_AND:
828     case BANG:
829+    case BAR_AND:
830     case DO:
831     case DONE:
832     case ELIF:
[973b90d5]833diff -Naur bash-4.0.orig/patchlevel.h bash-4.0/patchlevel.h
834--- bash-4.0.orig/patchlevel.h  2009-01-04 11:32:40.000000000 -0800
[8e00734]835+++ bash-4.0/patchlevel.h       2009-07-22 15:31:48.000000000 -0700
[973b90d5]836@@ -25,6 +25,6 @@
837    regexp `^#define[   ]*PATCHLEVEL', since that's what support/mkversion.sh
838    looks for to find the patch level (for the sccs version string). */
839 
840-#define PATCHLEVEL 0
[8e00734]841+#define PATCHLEVEL 28
[973b90d5]842 
843 #endif /* _PATCHLEVEL_H_ */
[c822ddc]844diff -Naur bash-4.0.orig/pcomplete.c bash-4.0/pcomplete.c
845--- bash-4.0.orig/pcomplete.c   2009-02-01 14:12:31.000000000 -0800
[8e00734]846+++ bash-4.0/pcomplete.c        2009-07-22 15:31:08.000000000 -0700
[c822ddc]847@@ -1032,6 +1032,7 @@
848   cmdlist = build_arg_list (funcname, text, lwords, cw);
849 
850   pps = &ps;
851+  save_parser_state (pps);
852   begin_unwind_frame ("gen-shell-function-matches");
853   add_unwind_protect (restore_parser_state, (char *)pps);
854   add_unwind_protect (dispose_words, (char *)cmdlist);
[e6b4db2]855diff -Naur bash-4.0.orig/sig.c bash-4.0/sig.c
856--- bash-4.0.orig/sig.c 2009-01-04 11:32:41.000000000 -0800
[8e00734]857+++ bash-4.0/sig.c      2009-07-22 15:31:28.000000000 -0700
[e6b4db2]858@@ -448,6 +448,48 @@
859 termsig_sighandler (sig)
860      int sig;
861 {
862+  /* If we get called twice with the same signal before handling it,
863+     terminate right away. */
864+  if (
865+#ifdef SIGHUP
866+    sig != SIGHUP &&
867+#endif
868+#ifdef SIGINT
869+    sig != SIGINT &&
870+#endif
871+#ifdef SIGDANGER
872+    sig != SIGDANGER &&
873+#endif
874+#ifdef SIGPIPE
875+    sig != SIGPIPE &&
876+#endif
877+#ifdef SIGALRM
878+    sig != SIGALRM &&
879+#endif
880+#ifdef SIGTERM
881+    sig != SIGTERM &&
882+#endif
883+#ifdef SIGXCPU
884+    sig != SIGXCPU &&
885+#endif
886+#ifdef SIGXFSZ
887+    sig != SIGXFSZ &&
888+#endif
889+#ifdef SIGVTALRM
890+    sig != SIGVTALRM &&
891+#endif
892+#ifdef SIGLOST
893+    sig != SIGLOST &&
894+#endif
895+#ifdef SIGUSR1
896+    sig != SIGUSR1 &&
897+#endif
898+#ifdef SIGUSR2
899+   sig != SIGUSR2 &&
900+#endif
901+   sig == terminating_signal)
902+    terminate_immediately = 1;
903+
904   terminating_signal = sig;
905 
906   /* XXX - should this also trigger when interrupt_immediately is set? */
[c822ddc]907diff -Naur bash-4.0.orig/subst.c bash-4.0/subst.c
908--- bash-4.0.orig/subst.c       2009-01-28 11:34:12.000000000 -0800
[8e00734]909+++ bash-4.0/subst.c    2009-07-22 15:31:48.000000000 -0700
[e6b4db2]910@@ -85,6 +85,7 @@
911 
912 /* Flags for the `pflags' argument to param_expand() */
913 #define PF_NOCOMSUB    0x01    /* Do not perform command substitution */
914+#define PF_IGNUNBOUND  0x02    /* ignore unbound vars even if -u set */
915 
916 /* These defs make it easier to use the editor. */
917 #define LBRACE         '{'
918@@ -222,6 +223,7 @@
[c822ddc]919 static int skip_double_quoted __P((char *, size_t, int));
920 static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
921 static char *extract_dollar_brace_string __P((char *, int *, int, int));
922+static int skip_matched_pair __P((const char *, int, int, int, int));
923 
924 static char *pos_params __P((char *, int, int, int));
925 
[e6b4db2]926@@ -262,7 +264,7 @@
927 static int chk_atstar __P((char *, int, int *, int *));
928 static int chk_arithsub __P((const char *, int));
929 
930-static WORD_DESC *parameter_brace_expand_word __P((char *, int, int));
931+static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int));
932 static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
933 static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
934 static void parameter_brace_expand_error __P((char *, char *));
935@@ -1374,6 +1376,107 @@
[c822ddc]936 
937 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
938 
939+/* This function assumes s[i] == open; returns with s[ret] == close; used to
940+   parse array subscripts.  FLAGS currently unused. */
941+static int
942+skip_matched_pair (string, start, open, close, flags)
943+     const char *string;
944+     int start, open, close, flags;
945+{
946+  int i, pass_next, backq, si, c, count;
947+  size_t slen;
948+  char *temp, *ss;
949+  DECLARE_MBSTATE;
950+
951+  slen = strlen (string + start) + start;
952+  no_longjmp_on_fatal_error = 1;
953+
954+  i = start + 1;               /* skip over leading bracket */
955+  count = 1;
956+  pass_next = backq = 0;
957+  ss = (char *)string;
958+  while (c = string[i])
959+    {
960+      if (pass_next)
961+       {
962+         pass_next = 0;
963+         if (c == 0)
964+           CQ_RETURN(i);
965+         ADVANCE_CHAR (string, slen, i);
966+         continue;
967+       }
968+      else if (c == '\\')
969+       {
970+         pass_next = 1;
971+         i++;
972+         continue;
973+       }
974+      else if (backq)
975+       {
976+         if (c == '`')
977+           backq = 0;
978+         ADVANCE_CHAR (string, slen, i);
979+         continue;
980+       }
981+      else if (c == '`')
982+       {
983+         backq = 1;
984+         i++;
985+         continue;
986+       }
987+      else if (c == open)
988+       {
989+         count++;
990+         i++;
991+         continue;
992+       }
993+      else if (c == close)
994+       {
995+         count--;
996+         if (count == 0)
997+           break;
998+         i++;
999+         continue;
1000+       }
1001+      else if (c == '\'' || c == '"')
1002+       {
1003+         i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
1004+                         : skip_double_quoted (ss, slen, ++i);
1005+         /* no increment, the skip functions increment past the closing quote. */
1006+       }
1007+      else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
1008+       {
1009+         si = i + 2;
1010+         if (string[si] == '\0')
1011+           CQ_RETURN(si);
1012+
1013+         if (string[i+1] == LPAREN)
1014+           temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
1015+         else
1016+           temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
1017+         i = si;
1018+         if (string[i] == '\0')        /* don't increment i past EOS in loop */
1019+           break;
1020+         i++;
1021+         continue;
1022+       }
1023+      else
1024+       ADVANCE_CHAR (string, slen, i);
1025+    }
1026+
1027+  CQ_RETURN(i);
1028+}
1029+
1030+#if defined (ARRAY_VARS)
1031+int
1032+skipsubscript (string, start)
1033+     const char *string;
1034+     int start;
1035+{
1036+  return (skip_matched_pair (string, start, '[', ']', 0));
1037+}
1038+#endif
1039+
1040 /* Skip characters in STRING until we find a character in DELIMS, and return
1041    the index of that character.  START is the index into string at which we
1042    begin.  This is similar in spirit to strpbrk, but it returns an index into
[e6b4db2]1043@@ -5093,9 +5196,9 @@
1044    the shell, e.g., "@", "$", "*", etc.  QUOTED, if non-zero, means that
1045    NAME was found inside of a double-quoted expression. */
1046 static WORD_DESC *
1047-parameter_brace_expand_word (name, var_is_special, quoted)
1048+parameter_brace_expand_word (name, var_is_special, quoted, pflags)
1049      char *name;
1050-     int var_is_special, quoted;
1051+     int var_is_special, quoted, pflags;
1052 {
1053   WORD_DESC *ret;
1054   char *temp, *tt;
1055@@ -5127,7 +5230,7 @@
1056       strcpy (tt + 1, name);
1057 
1058       ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
1059-                         (int *)NULL, (int *)NULL, 0);
1060+                         (int *)NULL, (int *)NULL, pflags);
1061       free (tt);
1062     }
1063 #if defined (ARRAY_VARS)
1064@@ -5188,7 +5291,7 @@
1065   char *temp, *t;
1066   WORD_DESC *w;
1067 
1068-  w = parameter_brace_expand_word (name, var_is_special, quoted);
1069+  w = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
1070   t = w->word;
1071   /* Have to dequote here if necessary */
1072   if (t)
1073@@ -5205,7 +5308,7 @@
1074   if (t == 0)
1075     return (WORD_DESC *)NULL;
1076 
1077-  w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted);
1078+  w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted, 0);
1079   free (t);
1080 
1081   return w;
1082@@ -6556,7 +6659,7 @@
1083   if (want_indir)
1084     tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
1085   else
1086-    tdesc = parameter_brace_expand_word (name, var_is_special, quoted);
1087+    tdesc = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
1088 
1089   if (tdesc)
1090     {
[8e00734]1091@@ -6664,13 +6767,13 @@
1092       return &expand_wdesc_error;
1093 
1094     case RBRACE:
1095-      if (var_is_set == 0 && unbound_vars_is_error)
1096+      if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]))
1097        {
1098+         last_command_exit_value = EXECUTION_FAILURE;
1099          err_unboundvar (name);
1100          FREE (value);
1101          FREE (temp);
1102          free (name);
1103-         last_command_exit_value = EXECUTION_FAILURE;
1104          return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
1105        }
1106       break;
1107@@ -6887,15 +6990,25 @@
[e6b4db2]1108     case '*':          /* `$*' */
1109       list = list_rest_of_args ();
1110 
1111-      if (list == 0 && unbound_vars_is_error)
[8e00734]1112+#if 0
1113+      /* According to austin-group posix proposal by Geoff Clare in
1114+        <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
1115+
1116+       "The shell shall write a message to standard error and
1117+        immediately exit when it tries to expand an unset parameter
1118+        other than the '@' and '*' special parameters."
1119+      */
1120+
[e6b4db2]1121+      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
1122        {
1123          uerror[0] = '$';
1124          uerror[1] = '*';
[8e00734]1125          uerror[2] = '\0';
1126-         err_unboundvar (uerror);
1127          last_command_exit_value = EXECUTION_FAILURE;
1128+         err_unboundvar (uerror);
1129          return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
1130        }
1131+#endif
1132 
1133       /* If there are no command-line arguments, this should just
1134         disappear if there are other characters in the expansion,
1135@@ -6949,15 +7062,25 @@
[e6b4db2]1136     case '@':          /* `$@' */
1137       list = list_rest_of_args ();
1138 
1139-      if (list == 0 && unbound_vars_is_error)
[8e00734]1140+#if 0
1141+      /* According to austin-group posix proposal by Geoff Clare in
1142+        <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
1143+
1144+       "The shell shall write a message to standard error and
1145+        immediately exit when it tries to expand an unset parameter
1146+        other than the '@' and '*' special parameters."
1147+      */
1148+
[e6b4db2]1149+      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
1150        {
1151          uerror[0] = '$';
1152          uerror[1] = '@';
[8e00734]1153          uerror[2] = '\0';
1154-         err_unboundvar (uerror);
1155          last_command_exit_value = EXECUTION_FAILURE;
1156+         err_unboundvar (uerror);
1157          return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
1158        }
1159+#endif
1160 
1161       /* We want to flag the fact that we saw this.  We can't turn
1162         off quoting entirely, because other characters in the
[e6b4db2]1163diff -Naur bash-4.0.orig/trap.c bash-4.0/trap.c
1164--- bash-4.0.orig/trap.c        2009-01-16 14:07:53.000000000 -0800
[8e00734]1165+++ bash-4.0/trap.c     2009-07-22 15:31:34.000000000 -0700
[e6b4db2]1166@@ -755,7 +755,7 @@
1167        }
1168 
1169       flags = SEVAL_NONINT|SEVAL_NOHIST;
1170-      if (sig != DEBUG_TRAP && sig != RETURN_TRAP)
1171+      if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP)
1172        flags |= SEVAL_RESETLINE;
1173       if (function_code == 0)
1174        parse_and_execute (trap_command, tag, flags);
[140d857]1175@@ -798,12 +798,36 @@
1176 run_debug_trap ()
1177 {
1178   int trap_exit_value;
1179+  pid_t save_pgrp;
1180+  int save_pipe[2];
1181 
1182   /* XXX - question:  should the DEBUG trap inherit the RETURN trap? */
1183   trap_exit_value = 0;
1184   if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && ((sigmodes[DEBUG_TRAP] & SIG_IGNORED) == 0) && ((sigmodes[DEBUG_TRAP] & SIG_INPROGRESS) == 0))
1185     {
1186+#if defined (JOB_CONTROL)
1187+      save_pgrp = pipeline_pgrp;
1188+      pipeline_pgrp = 0;
1189+      save_pipeline (1);
1190+#  if defined (PGRP_PIPE)
1191+      save_pgrp_pipe (save_pipe, 1);
1192+#  endif
1193+      stop_making_children ();
1194+#endif
1195+
1196       trap_exit_value = _run_trap_internal (DEBUG_TRAP, "debug trap");
1197+
1198+#if defined (JOB_CONTROL)
1199+      pipeline_pgrp = save_pgrp;
1200+      restore_pipeline (1);
1201+#  if defined (PGRP_PIPE)
1202+      close_pgrp_pipe ();
1203+      restore_pgrp_pipe (save_pipe);
1204+#  endif
1205+      if (pipeline_pgrp > 0)
1206+       give_terminal_to (pipeline_pgrp, 1);
1207+      notify_and_cleanup ();
1208+#endif
1209       
1210 #if defined (DEBUGGER)
1211       /* If we're in the debugger and the DEBUG trap returns 2 while we're in
Note: See TracBrowser for help on using the repository browser.