source: patches/bash-4.0-branch_update-7.patch @ 0cbb4b7

clfs-1.2clfs-2.1clfs-3.0.0-systemdclfs-3.0.0-sysvinitsystemdsysvinit
Last change on this file since 0cbb4b7 was 28428e9, checked in by jim <jim@…>, 15 years ago

Updated Bash Patch

  • Property mode set to 100644
File size: 42.8 KB
RevLine 
[c822ddc]1Submitted By: Jim Gifford (jim at cross-lfs dot org)
[28428e9]2Date: 09-12-2009
[c822ddc]3Initial Package Version: 4.0
4Origin: Upstream
5Upstream Status: Applied
[28428e9]6Description: Contains all upstream patches up to 4.0-033
[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
[28428e9]10+++ bash-4.0/arrayfunc.c        2009-09-12 08:23:47.000000000 -0700
11@@ -98,7 +98,7 @@
12   oldval = value_cell (var);
13   hash = assoc_create (0);
14   if (oldval)
15-    assoc_insert (hash, "0", oldval);
16+    assoc_insert (hash, savestring ("0"), oldval);
17 
18   FREE (value_cell (var));
19   var_setassoc (var, hash);
[c822ddc]20@@ -604,64 +604,7 @@
21     }
22 }
23 
24-/* This function assumes s[i] == '['; returns with s[ret] == ']' if
25-   an array subscript is correctly parsed. */
26-int
27-skipsubscript (s, i)
28-     const char *s;
29-     int i;
30-{
31-  int count, c;
32-#if defined (HANDLE_MULTIBYTE)
33-  mbstate_t state, state_bak;
34-  size_t slength, mblength;
35-#endif
36-
37-#if defined (HANDLE_MULTIBYTE)
38-  memset (&state, '\0', sizeof (mbstate_t));
39-  slength = strlen (s + i);
40-#endif
41
42-  count = 1;
43-  while (count)
44-    {
45-      /* Advance one (possibly multibyte) character in S starting at I. */
46-#if defined (HANDLE_MULTIBYTE)
47-      if (MB_CUR_MAX > 1)
48-       {
49-         state_bak = state;
50-         mblength = mbrlen (s + i, slength, &state);
51-
52-         if (MB_INVALIDCH (mblength))
53-           {
54-             state = state_bak;
55-             i++;
56-             slength--;
57-           }
58-         else if (MB_NULLWCH (mblength))
59-           return i;
60-         else
61-           {
62-             i += mblength;
63-             slength -= mblength;
64-           }
65-       }
66-      else
67-#endif
68-      ++i;
69-
70-      c = s[i];
71-
72-      if (c == 0)
73-       break;
74-      else if (c == '[')
75-       count++;
76-      else if (c == ']')
77-       count--;
78-    }
79-
80-  return i;
81-}
82+/* skipsubscript moved to subst.c to use private functions. 2009/02/24. */
83 
84 /* This function is called with SUB pointing to just after the beginning
85    `[' of an array subscript and removes the array element to which SUB
[28428e9]86diff -Naur bash-4.0.orig/bashline.c bash-4.0/bashline.c
87--- bash-4.0.orig/bashline.c    2009-01-08 06:29:24.000000000 -0800
88+++ bash-4.0/bashline.c 2009-09-12 08:23:46.000000000 -0700
89@@ -3388,7 +3388,6 @@
90   Keymap xkmap;                /* unix command executing keymap */
91   register int i;
92   intmax_t mi;
93-  int save_point;
94   sh_parser_state_t ps;
95   char *cmd, *value, *l;
96   SHELL_VAR *v;
97@@ -3432,7 +3431,6 @@
98   if (v)
99     VSETATTR (v, att_exported);
100   l = value_cell (v);
101-  save_point = rl_point;
102   value = inttostr (rl_point, ibuf, sizeof (ibuf));
103   v = bind_int_variable ("READLINE_POINT", value);
104   if (v)
105@@ -3450,7 +3448,7 @@
106   if (v && legal_number (value_cell (v), &mi))
107     {
108       i = mi;
109-      if (i != save_point)
110+      if (i != rl_point)
111        {
112          rl_point = i;
113          if (rl_point > rl_end)
[c822ddc]114diff -Naur bash-4.0.orig/builtins/declare.def bash-4.0/builtins/declare.def
115--- bash-4.0.orig/builtins/declare.def  2009-01-04 11:32:22.000000000 -0800
[28428e9]116+++ bash-4.0/builtins/declare.def       2009-09-12 08:23:07.000000000 -0700
[973b90d5]117@@ -295,6 +295,13 @@
[c822ddc]118       subscript_start = (char *)NULL;
119       if (t = strchr (name, '['))      /* ] */
120        {
121+         /* If offset != 0 we have already validated any array reference */
122+         if (offset == 0 && valid_array_reference (name) == 0)
123+           {
124+             sh_invalidid (name);
125+             assign_error++;
126+             NEXT_VARIABLE ();
127+           }
128          subscript_start = t;
129          *t = '\0';
130          making_array_special = 1;
[973b90d5]131@@ -484,7 +491,7 @@
[c822ddc]132            }
133          /* declare -a name[[n]] or declare name[n] makes name an indexed
134             array variable. */
135-         else if ((making_array_special || (flags_on & att_array)) && array_p (var) == 0)
136+         else if ((making_array_special || (flags_on & att_array)) && array_p (var) == 0 && assoc_p (var) == 0)
137            var = convert_var_to_array (var);
138 #endif /* ARRAY_VARS */
139 
140diff -Naur bash-4.0.orig/builtins/exit.def bash-4.0/builtins/exit.def
141--- bash-4.0.orig/builtins/exit.def     2009-01-04 11:32:22.000000000 -0800
[28428e9]142+++ bash-4.0/builtins/exit.def  2009-09-12 08:23:05.000000000 -0700
[c822ddc]143@@ -113,7 +113,7 @@
144       for (i = stopmsg = 0; i < js.j_jobslots; i++)
145        if (jobs[i] && STOPPED (i))
146          stopmsg = JSTOPPED;
147-       else if (check_jobs_at_exit && stopmsg == 0 && RUNNING (i))
148+       else if (check_jobs_at_exit && stopmsg == 0 && jobs[i] && RUNNING (i))
149          stopmsg = JRUNNING;
150 
151       if (stopmsg == JSTOPPED)
[e6b4db2]152diff -Naur bash-4.0.orig/builtins/fc.def bash-4.0/builtins/fc.def
153--- bash-4.0.orig/builtins/fc.def       2009-01-04 11:32:22.000000000 -0800
[28428e9]154+++ bash-4.0/builtins/fc.def    2009-09-12 08:23:21.000000000 -0700
[e6b4db2]155@@ -88,6 +88,7 @@
156 extern int current_command_line_count;
157 extern int literal_history;
158 extern int posixly_correct;
159+extern int subshell_environment, interactive_shell;
160 
161 extern int unlink __P((const char *));
162 
163@@ -172,7 +173,7 @@
164   register int i;
165   register char *sep;
166   int numbering, reverse, listing, execute;
167-  int histbeg, histend, last_hist, retval, opt;
168+  int histbeg, histend, last_hist, retval, opt, rh;
169   FILE *stream;
170   REPL *rlist, *rl;
171   char *ename, *command, *newcom, *fcedit;
172@@ -275,6 +276,8 @@
173 
174       fprintf (stderr, "%s\n", command);
175       fc_replhist (command);   /* replace `fc -s' with command */
176+      /* Posix says that the re-executed commands should be entered into the
177+        history. */
178       return (parse_and_execute (command, "fc", SEVAL_NOHIST));
179     }
180 
181@@ -293,7 +296,12 @@
182      line was actually added (HISTIGNORE may have caused it to not be),
183      so we check hist_last_line_added. */
184 
185-  last_hist = i - remember_on_history - hist_last_line_added;
186+  /* Even though command substitution through parse_and_execute turns off
187+     remember_on_history, command substitution in a shell when set -o history
188+     has been enabled (interactive or not) should use it in the last_hist
189+     calculation as if it were on. */
190+  rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
191+  last_hist = i - rh - hist_last_line_added;
192 
193   if (list)
194     {
195@@ -456,7 +464,7 @@
196      char *command;
197      HIST_ENTRY **hlist;
198 {
199-  int sign, n, clen;
200+  int sign, n, clen, rh;
201   register int i, j;
202   register char *s;
203 
204@@ -472,7 +480,12 @@
205      line was actually added (HISTIGNORE may have caused it to not be),
206      so we check hist_last_line_added.  This needs to agree with the
207      calculation of last_hist in fc_builtin above. */
208-  i -= remember_on_history + hist_last_line_added;
209+  /* Even though command substitution through parse_and_execute turns off
210+     remember_on_history, command substitution in a shell when set -o history
211+     has been enabled (interactive or not) should use it in the last_hist
212+     calculation as if it were on. */
213+  rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
214+  i -= rh + hist_last_line_added;
215 
216   /* No specification defaults to most recent command. */
217   if (command == NULL)
[7a39f29]218diff -Naur bash-4.0.orig/builtins/read.def bash-4.0/builtins/read.def
219--- bash-4.0.orig/builtins/read.def     2009-01-15 20:11:21.000000000 -0800
[28428e9]220+++ bash-4.0/builtins/read.def  2009-09-12 08:23:50.000000000 -0700
[7a39f29]221@@ -369,14 +369,14 @@
222       code = setjmp (alrmbuf);
223       if (code)
224        {
225-#if 0
226+         /* Tricky.  The top of the unwind-protect stack is the free of
227+            input_string.  We want to run all the rest and use input_string,
228+            so we have to remove it from the stack. */
229+         remove_unwind_protect ();
230          run_unwind_frame ("read_builtin");
231-         return (EXECUTION_FAILURE);
232-#else
233          input_string[i] = '\0';       /* make sure it's terminated */
234-         retval = 128+SIGALRM;;
235+         retval = 128+SIGALRM;
236          goto assign_vars;
237-#endif
238        }
239       old_alrm = set_signal_handler (SIGALRM, sigalrm);
240       add_unwind_protect (reset_alarm, (char *)NULL);
[28428e9]241@@ -763,7 +763,10 @@
242       if (*input_string == 0)
243        tofree = input_string = t;
244       else
245-       input_string = strip_trailing_ifs_whitespace (t1, ifs_chars, saw_escape);
246+       {
247+         input_string = strip_trailing_ifs_whitespace (t1, ifs_chars, saw_escape);
248+         tofree = t;
249+       }
250     }
251 #endif
252 
[8e00734]253diff -Naur bash-4.0.orig/doc/bash.1 bash-4.0/doc/bash.1
254--- bash-4.0.orig/doc/bash.1    2009-02-18 12:13:56.000000000 -0800
[28428e9]255+++ bash-4.0/doc/bash.1 2009-09-12 08:23:43.000000000 -0700
[8e00734]256@@ -8257,9 +8257,10 @@
257 Exit after reading and executing one command.
258 .TP 8
259 .B \-u
260-Treat unset variables as an error when performing
261+Treat unset variables and parameters other than the special
262+parameters "@" and "*" as an error when performing
263 parameter expansion.  If expansion is attempted on an
264-unset variable, the shell prints an error message, and,
265+unset variable or parameter, the shell prints an error message, and,
266 if not interactive, exits with a non-zero status.
267 .TP 8
268 .B \-v
269diff -Naur bash-4.0.orig/doc/bashref.texi bash-4.0/doc/bashref.texi
270--- bash-4.0.orig/doc/bashref.texi      2009-02-18 12:14:43.000000000 -0800
[28428e9]271+++ bash-4.0/doc/bashref.texi   2009-09-12 08:23:43.000000000 -0700
[8e00734]272@@ -4138,7 +4138,8 @@
273 Exit after reading and executing one command.
274 
275 @item -u
276-Treat unset variables as an error when performing parameter expansion.
277+Treat unset variables and parameters other than the special parameters
278+@samp{@@} or @samp{*} as an error when performing parameter expansion.
279 An error message will be written to the standard error, and a non-interactive
280 shell will exit.
281 
[e6b4db2]282diff -Naur bash-4.0.orig/execute_cmd.c bash-4.0/execute_cmd.c
283--- bash-4.0.orig/execute_cmd.c 2009-02-13 13:41:41.000000000 -0800
[28428e9]284+++ bash-4.0/execute_cmd.c      2009-09-12 08:23:24.000000000 -0700
[e6b4db2]285@@ -568,6 +568,7 @@
286 
287       /* Fork a subshell, turn off the subshell bit, turn off job
288         control and call execute_command () on the command again. */
289+      line_number_for_err_trap = line_number;
290       paren_pid = make_child (savestring (make_command_string (command)),
291                              asynchronous);
292       if (paren_pid == 0)
293@@ -610,7 +611,10 @@
294              if (user_subshell && was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
295                {
296                  last_command_exit_value = exec_result;
297+                 save_line_number = line_number;
298+                 line_number = line_number_for_err_trap;
299                  run_error_trap ();
300+                 line_number = save_line_number;
301                }
302 
303              if (user_subshell && ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
304@@ -766,7 +770,9 @@
305       if (was_error_trap && ignore_return == 0 && invert == 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS)
306        {
307          last_command_exit_value = exec_result;
308+         line_number = line_number_for_err_trap;
309          run_error_trap ();
310+         line_number = save_line_number;
311        }
312 
313       if (ignore_return == 0 && invert == 0 &&
314@@ -2105,6 +2111,7 @@
315   REDIRECT *rp;
316   COMMAND *tc, *second;
317   int ignore_return, exec_result, was_error_trap, invert;
318+  volatile int save_line_number;
319 
320   ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
321 
322@@ -2174,12 +2181,16 @@
323       invert = (command->flags & CMD_INVERT_RETURN) != 0;
324       ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
325 
326+      line_number_for_err_trap = line_number;
327       exec_result = execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close);
328 
329       if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
330        {
331          last_command_exit_value = exec_result;
332+         save_line_number = line_number;
333+         line_number = line_number_for_err_trap;
334          run_error_trap ();
335+         line_number = save_line_number;
336        }
337 
338       if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
339@@ -2930,7 +2941,7 @@
340                  retval = execute_command (clauses->action);
341                }
342              while ((clauses->flags & CASEPAT_FALLTHROUGH) && (clauses = clauses->next));
343-             if ((clauses->flags & CASEPAT_TESTNEXT) == 0)
344+             if (clauses == 0 || (clauses->flags & CASEPAT_TESTNEXT) == 0)
345                EXIT_CASE ();
346              else
347                break;
[8e00734]348diff -Naur bash-4.0.orig/externs.h bash-4.0/externs.h
349--- bash-4.0.orig/externs.h     2009-01-18 15:29:29.000000000 -0800
[28428e9]350+++ bash-4.0/externs.h  2009-09-12 08:23:39.000000000 -0700
[8e00734]351@@ -192,6 +192,8 @@
352 extern char *fmtumax __P((uintmax_t, int, char *, size_t, int));
353 
354 /* Declarations for functions defined in lib/sh/fpurge.c */
355+
356+#if defined NEED_FPURGE_DECL
357 #if !HAVE_DECL_FPURGE
358 
359 #if HAVE_FPURGE
360@@ -200,7 +202,7 @@
361 extern int fpurge __P((FILE *stream));
362 
363 #endif /* HAVE_DECL_FPURGE */
364-
365+#endif /* NEED_FPURGE_DECL */
366 
367 /* Declarations for functions defined in lib/sh/getcwd.c */
368 #if !defined (HAVE_GETCWD)
[140d857]369diff -Naur bash-4.0.orig/jobs.c bash-4.0/jobs.c
370--- bash-4.0.orig/jobs.c        2009-01-29 14:09:49.000000000 -0800
[28428e9]371+++ bash-4.0/jobs.c     2009-09-12 08:23:29.000000000 -0700
[140d857]372@@ -442,7 +442,7 @@
373   old_pipeline = the_pipeline;
374   the_pipeline = saved_pipeline;
375   already_making_children = saved_already_making_children;
376-  if (discard)
377+  if (discard && old_pipeline)
378     discard_pipeline (old_pipeline);
379 }
380 
381@@ -4202,4 +4202,23 @@
382   sh_closepipe (pgrp_pipe);
383 }
384 
385+void
386+save_pgrp_pipe (p, clear)
387+     int *p;
388+     int clear;
389+{
390+  p[0] = pgrp_pipe[0];
391+  p[1] = pgrp_pipe[1];
392+  if (clear)
393+    pgrp_pipe[0] = pgrp_pipe[1] = -1;
394+}
395+
396+void
397+restore_pgrp_pipe (p)
398+     int *p;
399+{
400+  pgrp_pipe[0] = p[0];
401+  pgrp_pipe[1] = p[1];
402+}
403+
404 #endif /* PGRP_PIPE */
405diff -Naur bash-4.0.orig/jobs.h bash-4.0/jobs.h
406--- bash-4.0.orig/jobs.h        2009-01-04 11:32:29.000000000 -0800
[28428e9]407+++ bash-4.0/jobs.h     2009-09-12 08:23:29.000000000 -0700
[140d857]408@@ -235,6 +235,8 @@
409 extern void init_job_stats __P((void));
410 
411 extern void close_pgrp_pipe __P((void));
412+extern void save_pgrp_pipe __P((int *, int));
413+extern void restore_pgrp_pipe __P((int *));
414 
415 #if defined (JOB_CONTROL)
416 extern int job_control;
417diff -Naur bash-4.0.orig/lib/glob/glob.c bash-4.0/lib/glob/glob.c
418--- bash-4.0.orig/lib/glob/glob.c       2009-01-04 11:32:30.000000000 -0800
[28428e9]419+++ bash-4.0/lib/glob/glob.c    2009-09-12 08:23:38.000000000 -0700
[140d857]420@@ -356,7 +356,7 @@
421        *np = 0;
422       if (ep)
423         *ep = 0;
424-      if (r)
425+      if (r && r != &glob_error_return)
426        free (r);
427       return (struct globval *)0;
428     }
[8e00734]429@@ -665,7 +665,9 @@
[140d857]430       (void) closedir (d);
431     }
432 
433-  /* compat: if GX_ALLDIRS, add the passed directory also */
[8e00734]434+  /* compat: if GX_ADDCURDIR, add the passed directory also.  Add an empty
435+     directory name as a placeholder if GX_NULLDIR (in which case the passed
436+     directory name is "."). */
437   if (add_current)
[140d857]438     {
439       sdlen = strlen (dir);
[8e00734]440@@ -942,7 +944,12 @@
[140d857]441              char **array;
442              register unsigned int l;
443 
444-             array = glob_dir_to_array (directories[i], temp_results, flags);
445+             /* If we're expanding **, we don't need to glue the directory
446+                name to the results; we've already done it in glob_vector */
447+             if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
448+               array = temp_results;
449+             else
450+               array = glob_dir_to_array (directories[i], temp_results, flags);
451              l = 0;
452              while (array[l] != NULL)
453                ++l;
[8e00734]454@@ -959,7 +966,8 @@
[140d857]455              result[result_size - 1] = NULL;
456 
457              /* Note that the elements of ARRAY are not freed.  */
458-             free ((char *) array);
459+             if (array != temp_results)
460+               free ((char *) array);
461            }
462        }
463       /* Free the directories.  */
[8e00734]464@@ -1003,11 +1011,24 @@
465 
466       /* Just return what glob_vector () returns appended to the
467         directory name. */
468+      /* If flags & GX_ALLDIRS, we're called recursively */
469       dflags = flags & ~GX_MARKDIRS;
470       if (directory_len == 0)
471        dflags |= GX_NULLDIR;
472       if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
473-       dflags |= GX_ALLDIRS|GX_ADDCURDIR;
474+       {
475+         dflags |= GX_ALLDIRS|GX_ADDCURDIR;
476+#if 0
477+         /* If we want all directories (dflags & GX_ALLDIRS) and we're not
478+            being called recursively as something like `echo **/*.o'
479+            ((flags & GX_ALLDIRS) == 0), we want to prevent glob_vector from
480+            adding a null directory name to the front of the temp_results
481+            array.  We turn off ADDCURDIR if not called recursively and
482+            dlen == 0 */
483+#endif
484+         if (directory_len == 0 && (flags & GX_ALLDIRS) == 0)
485+           dflags &= ~GX_ADDCURDIR;
486+       }
487       temp_results = glob_vector (filename,
488                                  (directory_len == 0 ? "." : directory_name),
489                                  dflags);
[140d857]490diff -Naur bash-4.0.orig/lib/readline/display.c bash-4.0/lib/readline/display.c
491--- bash-4.0.orig/lib/readline/display.c        2009-01-04 11:32:32.000000000 -0800
[28428e9]492+++ bash-4.0/lib/readline/display.c     2009-09-12 08:23:41.000000000 -0700
[140d857]493@@ -512,6 +512,7 @@
494   /* Block keyboard interrupts because this function manipulates global
495      data structures. */
496   _rl_block_sigint (); 
497+  RL_SETSTATE (RL_STATE_REDISPLAYING);
498 
499   if (!rl_display_prompt)
500     rl_display_prompt = "";
[8e00734]501@@ -1188,9 +1189,11 @@
502       if (t < out)
503        line[t - 1] = '>';
504 
505-      if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
506+      if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin)
507        {
508          forced_display = 0;
509+         o_cpos = _rl_last_c_pos;
510+         cpos_adjusted = 0;
511          update_line (&visible_line[last_lmargin],
512                       &invisible_line[lmargin],
513                       0,
514@@ -1198,6 +1201,13 @@
515                       _rl_screenwidth + (lmargin ? 0 : wrap_offset),
516                       0);
517 
518+         if ((MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
519+             cpos_adjusted == 0 &&
520+             _rl_last_c_pos != o_cpos &&
521+             _rl_last_c_pos > wrap_offset &&
522+             o_cpos < prompt_last_invisible)
523+               _rl_last_c_pos -= prompt_invis_chars_first_line;        /* XXX - was wrap_offset */
524+
525          /* If the visible new line is shorter than the old, but the number
526             of invisible characters is greater, and we are at the end of
527             the new line, we need to clear to eol. */
528@@ -1236,6 +1246,7 @@
[140d857]529       visible_wrap_offset = wrap_offset;
530   }
531 
532+  RL_UNSETSTATE (RL_STATE_REDISPLAYING);
533   _rl_release_sigint ();
534 }
535 
[8e00734]536@@ -1772,7 +1783,7 @@
[140d857]537             space_to_eol will insert too many spaces.  XXX - maybe we should
538             adjust col_lendiff based on the difference between _rl_last_c_pos
539             and _rl_screenwidth */
540-         if (col_lendiff && (_rl_last_c_pos < _rl_screenwidth))
541+         if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
542 #endif
543            {     
544              if (_rl_term_autowrap && current_line < inv_botlin)
[8e00734]545@@ -1892,6 +1903,10 @@
[140d857]546 
547   woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
548   cpos = _rl_last_c_pos;
549+
550+  if (cpos == 0 && cpos == new)
551+    return;
552+
553 #if defined (HANDLE_MULTIBYTE)
554   /* If we have multibyte characters, NEW is indexed by the buffer point in
555      a multibyte string, but _rl_last_c_pos is the display position.  In
[8e00734]556@@ -1905,9 +1920,9 @@
[140d857]557         prompt string, since they're both buffer indices and DPOS is a
558         desired display position. */
559       if ((new > prompt_last_invisible) ||             /* XXX - don't use woff here */
560-         (prompt_physical_chars > _rl_screenwidth &&
561+         (prompt_physical_chars >= _rl_screenwidth &&
562           _rl_last_v_pos == prompt_last_screen_line &&
563-          wrap_offset >= woff &&
564+          wrap_offset >= woff && dpos >= woff &&
565           new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset)))
566           /* XXX last comparison might need to be >= */
567        {
568diff -Naur bash-4.0.orig/lib/readline/readline.h bash-4.0/lib/readline/readline.h
569--- bash-4.0.orig/lib/readline/readline.h       2009-01-04 11:32:33.000000000 -0800
[28428e9]570+++ bash-4.0/lib/readline/readline.h    2009-09-12 08:23:30.000000000 -0700
[140d857]571@@ -814,8 +814,9 @@
572 #define RL_STATE_VIMOTION      0x100000        /* reading vi motion arg */
573 #define RL_STATE_MULTIKEY      0x200000        /* reading multiple-key command */
574 #define RL_STATE_VICMDONCE     0x400000        /* entered vi command mode at least once */
575+#define RL_STATE_REDISPLAYING  0x800000        /* updating terminal display */
576 
577-#define RL_STATE_DONE          0x800000        /* done; accepted line */
578+#define RL_STATE_DONE          0x1000000       /* done; accepted line */
579 
580 #define RL_SETSTATE(x)         (rl_readline_state |= (x))
581 #define RL_UNSETSTATE(x)       (rl_readline_state &= ~(x))
582diff -Naur bash-4.0.orig/lib/readline/terminal.c bash-4.0/lib/readline/terminal.c
583--- bash-4.0.orig/lib/readline/terminal.c       2009-01-04 11:32:34.000000000 -0800
[28428e9]584+++ bash-4.0/lib/readline/terminal.c    2009-09-12 08:23:30.000000000 -0700
[140d857]585@@ -355,7 +355,7 @@
586       _rl_get_screen_size (fileno (rl_instream), 1);
587       if (CUSTOM_REDISPLAY_FUNC ())
588        rl_forced_update_display ();
589-      else
590+      else if (RL_ISSTATE(RL_STATE_REDISPLAYING) == 0)
591        _rl_redisplay_after_sigwinch ();
592     }
593 }
594diff -Naur bash-4.0.orig/lib/sh/winsize.c bash-4.0/lib/sh/winsize.c
595--- bash-4.0.orig/lib/sh/winsize.c      2008-08-12 10:53:51.000000000 -0700
[28428e9]596+++ bash-4.0/lib/sh/winsize.c   2009-09-12 08:23:27.000000000 -0700
[140d857]597@@ -30,16 +30,29 @@
598 
599 #include <sys/ioctl.h>
600 
601-#if !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
602-/* For struct winsize on SCO */
603-/*   sys/ptem.h has winsize but needs mblk_t from sys/stream.h */
604-#  if defined (HAVE_SYS_PTEM_H) && defined (TIOCGWINSZ) && defined (SIGWINCH)
605-#    if defined (HAVE_SYS_STREAM_H)
606-#      include <sys/stream.h>
607-#    endif
608+/* Try to find the definitions of `struct winsize' and TIOGCWINSZ */
609+
610+#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
611+#  include <sys/ioctl.h>
612+#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
613+
614+#if defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
615+#  include <termios.h>
616+#endif /* STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */
617+
618+/* Not in either of the standard places, look around. */
619+#if !defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
620+#  if defined (HAVE_SYS_STREAM_H)
621+#    include <sys/stream.h>
622+#  endif /* HAVE_SYS_STREAM_H */
623+#  if defined (HAVE_SYS_PTEM_H) /* SVR4.2, at least, has it here */
624 #    include <sys/ptem.h>
625-#  endif /* HAVE_SYS_PTEM_H && TIOCGWINSZ && SIGWINCH */
626-#endif /* !STRUCT_WINSIZE_IN_SYS_IOCTL */
627+#    define _IO_PTEM_H          /* work around SVR4.2 1.1.4 bug */
628+#  endif /* HAVE_SYS_PTEM_H */
629+#  if defined (HAVE_SYS_PTE_H)  /* ??? */
630+#    include <sys/pte.h>
631+#  endif /* HAVE_SYS_PTE_H */
632+#endif /* !STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */
633 
634 #include <stdio.h>
635 
[c822ddc]636diff -Naur bash-4.0.orig/parse.y bash-4.0/parse.y
637--- bash-4.0.orig/parse.y       2009-01-08 05:29:12.000000000 -0800
[28428e9]638+++ bash-4.0/parse.y    2009-09-12 08:23:33.000000000 -0700
[e6b4db2]639@@ -1122,7 +1122,7 @@
640                          REDIRECTEE rd;
641                          REDIRECT *r;
642 
643-                         tc = $1;
644+                         tc = $1->type == cm_simple ? (COMMAND *)$1->value.Simple : $1;
645                          rd.dest = 1;
646                          r = make_redirection (2, r_duplicating_output, rd);
647                          if (tc->redirects)
[c822ddc]648@@ -1615,10 +1615,11 @@
649 {
650   int *ret;
651 
652-  ret = (int *)xmalloc (3 * sizeof (int));
653+  ret = (int *)xmalloc (4 * sizeof (int));
654   ret[0] = last_read_token;
655   ret[1] = token_before_that;
656   ret[2] = two_tokens_ago;
657+  ret[3] = current_token;
658   return ret;
659 }
660 
661@@ -1631,6 +1632,7 @@
662   last_read_token = ts[0];
663   token_before_that = ts[1];
664   two_tokens_ago = ts[2];
665+  current_token = ts[3];
666 }
667 
668 /*
[e6b4db2]669@@ -1877,7 +1879,7 @@
670     prompt_again ();
671   ret = read_a_line (remove_quoted_newline);
672 #if defined (HISTORY)
673-  if (remember_on_history && (parser_state & PST_HEREDOC))
674+  if (ret && remember_on_history && (parser_state & PST_HEREDOC))
675     {
676       /* To make adding the the here-document body right, we need to rely
677         on history_delimiting_chars() returning \n for the first line of
[c822ddc]678@@ -2668,6 +2670,7 @@
679   FREE (word_desc_to_read);
680   word_desc_to_read = (WORD_DESC *)NULL;
681 
682+  current_token = '\n';                /* XXX */
683   last_read_token = '\n';
684   token_to_read = '\n';
685 }
686@@ -2915,6 +2918,7 @@
687 #define P_DQUOTE       0x04
688 #define P_COMMAND      0x08    /* parsing a command, so look for comments */
689 #define P_BACKQUOTE    0x10    /* parsing a backquoted command substitution */
690+#define P_ARRAYSUB     0x20    /* parsing a [...] array subscript for assignment */
691 
692 /* Lexical state while parsing a grouping construct or $(...). */
693 #define LEX_WASDOL     0x001
[973b90d5]694@@ -2927,6 +2931,7 @@
695 #define LEX_INHEREDOC  0x080
696 #define LEX_HEREDELIM  0x100           /* reading here-doc delimiter */
697 #define LEX_STRIPDOC   0x200           /* <<- strip tabs from here doc delim */
698+#define LEX_INWORD     0x400
699 
700 #define COMSUB_META(ch)                ((ch) == ';' || (ch) == '&' || (ch) == '|')
701 
702@@ -3129,6 +3134,8 @@
[c822ddc]703              APPEND_NESTRET ();
704              FREE (nestret);
705            }
706+         else if ((flags & P_ARRAYSUB) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))      /* ) } ] */
707+           goto parse_dollar_word;
708        }
709       /* Parse an old-style command substitution within double quotes as a
710         single word. */
[973b90d5]711@@ -3145,6 +3152,7 @@
[c822ddc]712       else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '['))    /* ) } ] */
713        /* check for $(), $[], or ${} inside quoted string. */
714        {
715+parse_dollar_word:
716          if (open == ch)       /* undo previous increment */
717            count--;
718          if (ch == '(')                /* ) */
[973b90d5]719@@ -3179,7 +3187,7 @@
720      int open, close;
721      int *lenp, flags;
722 {
723-  int count, ch, peekc, tflags, lex_rwlen, lex_firstind;
724+  int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
725   int nestlen, ttranslen, start_lineno;
726   char *ret, *nestret, *ttrans, *heredelim;
727   int retind, retsize, rflags, hdlen;
728@@ -3200,7 +3208,7 @@
729   retind = 0;
730 
731   start_lineno = line_number;
732-  lex_rwlen = 0;
733+  lex_rwlen = lex_wlen = 0;
734 
735   heredelim = 0;
736   lex_firstind = -1;
737@@ -3267,6 +3275,46 @@
738          continue;
[c822ddc]739        }
740 
[973b90d5]741+      if (tflags & LEX_PASSNEXT)               /* last char was backslash */
742+       {
743+/*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
744+         tflags &= ~LEX_PASSNEXT;
745+         if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
746+           {
747+             if (retind > 0)
748+               retind--;       /* swallow previously-added backslash */
749+             continue;
750+           }
751+
752+         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
753+         if MBTEST(ch == CTLESC || ch == CTLNUL)
754+           ret[retind++] = CTLESC;
755+         ret[retind++] = ch;
756+         continue;
757+       }
758+
759+      /* If this is a shell break character, we are not in a word.  If not,
760+        we either start or continue a word. */
761+      if MBTEST(shellbreak (ch))
762+       {
763+         tflags &= ~LEX_INWORD;
764+/*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
765+       }
766+      else
767+       {
768+         if (tflags & LEX_INWORD)
769+           {
770+             lex_wlen++;
771+/*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
772+           }         
773+         else
774+           {
775+/*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
776+             tflags |= LEX_INWORD;
777+             lex_wlen = 0;
778+           }
779+       }
780+
781       /* Skip whitespace */
782       if MBTEST(shellblank (ch) && lex_rwlen == 0)
783         {
[140d857]784@@ -3306,7 +3354,7 @@
785        }
786 
787       /* Meta-characters that can introduce a reserved word.  Not perfect yet. */
788-      if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && shellmeta(ch))
789+      if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && (shellmeta(ch) || ch == '\n'))
790        {
791          /* Add this character. */
792          RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
[973b90d5]793@@ -3364,9 +3412,21 @@
794 }             
795              tflags &= ~LEX_RESWDOK;
796            }
797-         else if (shellbreak (ch) == 0)
798+         else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
799+           ;   /* don't modify LEX_RESWDOK if we're starting a comment */
800+         else if MBTEST((tflags & LEX_INCASE) && ch != '\n')
801+           /* If we can read a reserved word and we're in case, we're at the
802+              point where we can read a new pattern list or an esac.  We
803+              handle the esac case above.  If we read a newline, we want to
804+              leave LEX_RESWDOK alone.  If we read anything else, we want to
805+              turn off LEX_RESWDOK, since we're going to read a pattern list. */
806 {
807-             tflags &= ~LEX_RESWDOK;
808+           tflags &= ~LEX_RESWDOK;
809+/*itrace("parse_comsub:%d: lex_incase == 1 found `%c', lex_reswordok -> 0", line_number, ch);*/
810+}
811+         else if MBTEST(shellbreak (ch) == 0)
812+{
813+           tflags &= ~LEX_RESWDOK;
814 /*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
815 }
816        }
817@@ -3394,36 +3454,23 @@
[c822ddc]818                }
819              else
820                shell_ungetc (peekc);
821-             tflags |= LEX_HEREDELIM;
822-             lex_firstind = -1;
823+             if (peekc != '<')
824+               {
825+                 tflags |= LEX_HEREDELIM;
826+                 lex_firstind = -1;
827+               }
828              continue;
829            }
830          else
[973b90d5]831-           ch = peekc;         /* fall through and continue XXX - this skips comments if peekc == '#' */
832+           ch = peekc;         /* fall through and continue XXX */
833        }
834-      /* Not exactly right yet, should handle shell metacharacters, too.  If
835-        any changes are made to this test, make analogous changes to subst.c:
836-        extract_delimited_string(). */
837-      else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
838+      else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
839+{
840+/*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
841        tflags |= LEX_INCOMMENT;
842+}
843 
844-      if (tflags & LEX_PASSNEXT)               /* last char was backslash */
845-       {
846-         tflags &= ~LEX_PASSNEXT;
847-         if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
848-           {
849-             if (retind > 0)
850-               retind--;       /* swallow previously-added backslash */
851-             continue;
852-           }
853-
854-         RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
855-         if MBTEST(ch == CTLESC || ch == CTLNUL)
856-           ret[retind++] = CTLESC;
857-         ret[retind++] = ch;
858-         continue;
859-       }
860-      else if MBTEST(ch == CTLESC || ch == CTLNUL)     /* special shell escapes */
861+      if MBTEST(ch == CTLESC || ch == CTLNUL)  /* special shell escapes */
862        {
863          RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
864          ret[retind++] = CTLESC;
865@@ -4248,7 +4295,7 @@
[c822ddc]866                     ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
867                      (token_index == 0 && (parser_state&PST_COMPASSIGN))))
868         {
869-         ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
870+         ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
871          if (ttok == &matched_pair_error)
872            return -1;          /* Bail immediately. */
873          RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
[973b90d5]874@@ -4449,6 +4496,7 @@
[c822ddc]875     case '}':          /* XXX */
876     case AND_AND:
877     case BANG:
878+    case BAR_AND:
879     case DO:
880     case DONE:
881     case ELIF:
[973b90d5]882diff -Naur bash-4.0.orig/patchlevel.h bash-4.0/patchlevel.h
883--- bash-4.0.orig/patchlevel.h  2009-01-04 11:32:40.000000000 -0800
[28428e9]884+++ bash-4.0/patchlevel.h       2009-09-12 08:23:50.000000000 -0700
[973b90d5]885@@ -25,6 +25,6 @@
886    regexp `^#define[   ]*PATCHLEVEL', since that's what support/mkversion.sh
887    looks for to find the patch level (for the sccs version string). */
888 
889-#define PATCHLEVEL 0
[28428e9]890+#define PATCHLEVEL 33
[973b90d5]891 
892 #endif /* _PATCHLEVEL_H_ */
[c822ddc]893diff -Naur bash-4.0.orig/pcomplete.c bash-4.0/pcomplete.c
894--- bash-4.0.orig/pcomplete.c   2009-02-01 14:12:31.000000000 -0800
[28428e9]895+++ bash-4.0/pcomplete.c        2009-09-12 08:23:02.000000000 -0700
[c822ddc]896@@ -1032,6 +1032,7 @@
897   cmdlist = build_arg_list (funcname, text, lwords, cw);
898 
899   pps = &ps;
900+  save_parser_state (pps);
901   begin_unwind_frame ("gen-shell-function-matches");
902   add_unwind_protect (restore_parser_state, (char *)pps);
903   add_unwind_protect (dispose_words, (char *)cmdlist);
[e6b4db2]904diff -Naur bash-4.0.orig/sig.c bash-4.0/sig.c
905--- bash-4.0.orig/sig.c 2009-01-04 11:32:41.000000000 -0800
[28428e9]906+++ bash-4.0/sig.c      2009-09-12 08:23:22.000000000 -0700
[e6b4db2]907@@ -448,6 +448,48 @@
908 termsig_sighandler (sig)
909      int sig;
910 {
911+  /* If we get called twice with the same signal before handling it,
912+     terminate right away. */
913+  if (
914+#ifdef SIGHUP
915+    sig != SIGHUP &&
916+#endif
917+#ifdef SIGINT
918+    sig != SIGINT &&
919+#endif
920+#ifdef SIGDANGER
921+    sig != SIGDANGER &&
922+#endif
923+#ifdef SIGPIPE
924+    sig != SIGPIPE &&
925+#endif
926+#ifdef SIGALRM
927+    sig != SIGALRM &&
928+#endif
929+#ifdef SIGTERM
930+    sig != SIGTERM &&
931+#endif
932+#ifdef SIGXCPU
933+    sig != SIGXCPU &&
934+#endif
935+#ifdef SIGXFSZ
936+    sig != SIGXFSZ &&
937+#endif
938+#ifdef SIGVTALRM
939+    sig != SIGVTALRM &&
940+#endif
941+#ifdef SIGLOST
942+    sig != SIGLOST &&
943+#endif
944+#ifdef SIGUSR1
945+    sig != SIGUSR1 &&
946+#endif
947+#ifdef SIGUSR2
948+   sig != SIGUSR2 &&
949+#endif
950+   sig == terminating_signal)
951+    terminate_immediately = 1;
952+
953   terminating_signal = sig;
954 
955   /* XXX - should this also trigger when interrupt_immediately is set? */
[c822ddc]956diff -Naur bash-4.0.orig/subst.c bash-4.0/subst.c
957--- bash-4.0.orig/subst.c       2009-01-28 11:34:12.000000000 -0800
[28428e9]958+++ bash-4.0/subst.c    2009-09-12 08:23:49.000000000 -0700
[e6b4db2]959@@ -85,6 +85,7 @@
960 
961 /* Flags for the `pflags' argument to param_expand() */
962 #define PF_NOCOMSUB    0x01    /* Do not perform command substitution */
963+#define PF_IGNUNBOUND  0x02    /* ignore unbound vars even if -u set */
964 
965 /* These defs make it easier to use the editor. */
966 #define LBRACE         '{'
967@@ -222,6 +223,7 @@
[c822ddc]968 static int skip_double_quoted __P((char *, size_t, int));
969 static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
970 static char *extract_dollar_brace_string __P((char *, int *, int, int));
971+static int skip_matched_pair __P((const char *, int, int, int, int));
972 
973 static char *pos_params __P((char *, int, int, int));
974 
[e6b4db2]975@@ -262,7 +264,7 @@
976 static int chk_atstar __P((char *, int, int *, int *));
977 static int chk_arithsub __P((const char *, int));
978 
979-static WORD_DESC *parameter_brace_expand_word __P((char *, int, int));
980+static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int));
981 static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
982 static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
983 static void parameter_brace_expand_error __P((char *, char *));
984@@ -1374,6 +1376,107 @@
[c822ddc]985 
986 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
987 
988+/* This function assumes s[i] == open; returns with s[ret] == close; used to
989+   parse array subscripts.  FLAGS currently unused. */
990+static int
991+skip_matched_pair (string, start, open, close, flags)
992+     const char *string;
993+     int start, open, close, flags;
994+{
995+  int i, pass_next, backq, si, c, count;
996+  size_t slen;
997+  char *temp, *ss;
998+  DECLARE_MBSTATE;
999+
1000+  slen = strlen (string + start) + start;
1001+  no_longjmp_on_fatal_error = 1;
1002+
1003+  i = start + 1;               /* skip over leading bracket */
1004+  count = 1;
1005+  pass_next = backq = 0;
1006+  ss = (char *)string;
1007+  while (c = string[i])
1008+    {
1009+      if (pass_next)
1010+       {
1011+         pass_next = 0;
1012+         if (c == 0)
1013+           CQ_RETURN(i);
1014+         ADVANCE_CHAR (string, slen, i);
1015+         continue;
1016+       }
1017+      else if (c == '\\')
1018+       {
1019+         pass_next = 1;
1020+         i++;
1021+         continue;
1022+       }
1023+      else if (backq)
1024+       {
1025+         if (c == '`')
1026+           backq = 0;
1027+         ADVANCE_CHAR (string, slen, i);
1028+         continue;
1029+       }
1030+      else if (c == '`')
1031+       {
1032+         backq = 1;
1033+         i++;
1034+         continue;
1035+       }
1036+      else if (c == open)
1037+       {
1038+         count++;
1039+         i++;
1040+         continue;
1041+       }
1042+      else if (c == close)
1043+       {
1044+         count--;
1045+         if (count == 0)
1046+           break;
1047+         i++;
1048+         continue;
1049+       }
1050+      else if (c == '\'' || c == '"')
1051+       {
1052+         i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
1053+                         : skip_double_quoted (ss, slen, ++i);
1054+         /* no increment, the skip functions increment past the closing quote. */
1055+       }
1056+      else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
1057+       {
1058+         si = i + 2;
1059+         if (string[si] == '\0')
1060+           CQ_RETURN(si);
1061+
1062+         if (string[i+1] == LPAREN)
1063+           temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
1064+         else
1065+           temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
1066+         i = si;
1067+         if (string[i] == '\0')        /* don't increment i past EOS in loop */
1068+           break;
1069+         i++;
1070+         continue;
1071+       }
1072+      else
1073+       ADVANCE_CHAR (string, slen, i);
1074+    }
1075+
1076+  CQ_RETURN(i);
1077+}
1078+
1079+#if defined (ARRAY_VARS)
1080+int
1081+skipsubscript (string, start)
1082+     const char *string;
1083+     int start;
1084+{
1085+  return (skip_matched_pair (string, start, '[', ']', 0));
1086+}
1087+#endif
1088+
1089 /* Skip characters in STRING until we find a character in DELIMS, and return
1090    the index of that character.  START is the index into string at which we
1091    begin.  This is similar in spirit to strpbrk, but it returns an index into
[e6b4db2]1092@@ -5093,9 +5196,9 @@
1093    the shell, e.g., "@", "$", "*", etc.  QUOTED, if non-zero, means that
1094    NAME was found inside of a double-quoted expression. */
1095 static WORD_DESC *
1096-parameter_brace_expand_word (name, var_is_special, quoted)
1097+parameter_brace_expand_word (name, var_is_special, quoted, pflags)
1098      char *name;
1099-     int var_is_special, quoted;
1100+     int var_is_special, quoted, pflags;
1101 {
1102   WORD_DESC *ret;
1103   char *temp, *tt;
1104@@ -5127,7 +5230,7 @@
1105       strcpy (tt + 1, name);
1106 
1107       ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
1108-                         (int *)NULL, (int *)NULL, 0);
1109+                         (int *)NULL, (int *)NULL, pflags);
1110       free (tt);
1111     }
1112 #if defined (ARRAY_VARS)
1113@@ -5188,7 +5291,7 @@
1114   char *temp, *t;
1115   WORD_DESC *w;
1116 
1117-  w = parameter_brace_expand_word (name, var_is_special, quoted);
1118+  w = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
1119   t = w->word;
1120   /* Have to dequote here if necessary */
1121   if (t)
1122@@ -5205,7 +5308,7 @@
1123   if (t == 0)
1124     return (WORD_DESC *)NULL;
1125 
1126-  w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted);
1127+  w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted, 0);
1128   free (t);
1129 
1130   return w;
[28428e9]1131@@ -6503,7 +6606,7 @@
1132            *contains_dollar_at = 1;
1133        }
1134       free (x);
1135-      free (xlist);
1136+      dispose_words (xlist);
1137       free (temp1);
1138       *indexp = sindex;
1139 
[e6b4db2]1140@@ -6556,7 +6659,7 @@
1141   if (want_indir)
1142     tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
1143   else
1144-    tdesc = parameter_brace_expand_word (name, var_is_special, quoted);
1145+    tdesc = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
1146 
1147   if (tdesc)
1148     {
[8e00734]1149@@ -6664,13 +6767,13 @@
1150       return &expand_wdesc_error;
1151 
1152     case RBRACE:
1153-      if (var_is_set == 0 && unbound_vars_is_error)
1154+      if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]))
1155        {
1156+         last_command_exit_value = EXECUTION_FAILURE;
1157          err_unboundvar (name);
1158          FREE (value);
1159          FREE (temp);
1160          free (name);
1161-         last_command_exit_value = EXECUTION_FAILURE;
1162          return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
1163        }
1164       break;
1165@@ -6887,15 +6990,25 @@
[e6b4db2]1166     case '*':          /* `$*' */
1167       list = list_rest_of_args ();
1168 
1169-      if (list == 0 && unbound_vars_is_error)
[8e00734]1170+#if 0
1171+      /* According to austin-group posix proposal by Geoff Clare in
1172+        <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
1173+
1174+       "The shell shall write a message to standard error and
1175+        immediately exit when it tries to expand an unset parameter
1176+        other than the '@' and '*' special parameters."
1177+      */
1178+
[e6b4db2]1179+      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
1180        {
1181          uerror[0] = '$';
1182          uerror[1] = '*';
[8e00734]1183          uerror[2] = '\0';
1184-         err_unboundvar (uerror);
1185          last_command_exit_value = EXECUTION_FAILURE;
1186+         err_unboundvar (uerror);
1187          return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
1188        }
1189+#endif
1190 
1191       /* If there are no command-line arguments, this should just
1192         disappear if there are other characters in the expansion,
1193@@ -6949,15 +7062,25 @@
[e6b4db2]1194     case '@':          /* `$@' */
1195       list = list_rest_of_args ();
1196 
1197-      if (list == 0 && unbound_vars_is_error)
[8e00734]1198+#if 0
1199+      /* According to austin-group posix proposal by Geoff Clare in
1200+        <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
1201+
1202+       "The shell shall write a message to standard error and
1203+        immediately exit when it tries to expand an unset parameter
1204+        other than the '@' and '*' special parameters."
1205+      */
1206+
[e6b4db2]1207+      if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
1208        {
1209          uerror[0] = '$';
1210          uerror[1] = '@';
[8e00734]1211          uerror[2] = '\0';
1212-         err_unboundvar (uerror);
1213          last_command_exit_value = EXECUTION_FAILURE;
1214+         err_unboundvar (uerror);
1215          return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
1216        }
1217+#endif
1218 
1219       /* We want to flag the fact that we saw this.  We can't turn
1220         off quoting entirely, because other characters in the
[e6b4db2]1221diff -Naur bash-4.0.orig/trap.c bash-4.0/trap.c
1222--- bash-4.0.orig/trap.c        2009-01-16 14:07:53.000000000 -0800
[28428e9]1223+++ bash-4.0/trap.c     2009-09-12 08:23:29.000000000 -0700
[e6b4db2]1224@@ -755,7 +755,7 @@
1225        }
1226 
1227       flags = SEVAL_NONINT|SEVAL_NOHIST;
1228-      if (sig != DEBUG_TRAP && sig != RETURN_TRAP)
1229+      if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP)
1230        flags |= SEVAL_RESETLINE;
1231       if (function_code == 0)
1232        parse_and_execute (trap_command, tag, flags);
[140d857]1233@@ -798,12 +798,36 @@
1234 run_debug_trap ()
1235 {
1236   int trap_exit_value;
1237+  pid_t save_pgrp;
1238+  int save_pipe[2];
1239 
1240   /* XXX - question:  should the DEBUG trap inherit the RETURN trap? */
1241   trap_exit_value = 0;
1242   if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && ((sigmodes[DEBUG_TRAP] & SIG_IGNORED) == 0) && ((sigmodes[DEBUG_TRAP] & SIG_INPROGRESS) == 0))
1243     {
1244+#if defined (JOB_CONTROL)
1245+      save_pgrp = pipeline_pgrp;
1246+      pipeline_pgrp = 0;
1247+      save_pipeline (1);
1248+#  if defined (PGRP_PIPE)
1249+      save_pgrp_pipe (save_pipe, 1);
1250+#  endif
1251+      stop_making_children ();
1252+#endif
1253+
1254       trap_exit_value = _run_trap_internal (DEBUG_TRAP, "debug trap");
1255+
1256+#if defined (JOB_CONTROL)
1257+      pipeline_pgrp = save_pgrp;
1258+      restore_pipeline (1);
1259+#  if defined (PGRP_PIPE)
1260+      close_pgrp_pipe ();
1261+      restore_pgrp_pipe (save_pipe);
1262+#  endif
1263+      if (pipeline_pgrp > 0)
1264+       give_terminal_to (pipeline_pgrp, 1);
1265+      notify_and_cleanup ();
1266+#endif
1267       
1268 #if defined (DEBUGGER)
1269       /* If we're in the debugger and the DEBUG trap returns 2 while we're in
[28428e9]1270diff -Naur bash-4.0.orig/variables.c bash-4.0/variables.c
1271--- bash-4.0.orig/variables.c   2009-01-04 11:32:46.000000000 -0800
1272+++ bash-4.0/variables.c        2009-09-12 08:23:47.000000000 -0700
1273@@ -252,6 +252,7 @@
1274 
1275 static int visible_var __P((SHELL_VAR *));
1276 static int visible_and_exported __P((SHELL_VAR *));
1277+static int export_environment_candidate __P((SHELL_VAR *));
1278 static int local_and_exported __P((SHELL_VAR *));
1279 static int variable_in_context __P((SHELL_VAR *));
1280 #if defined (ARRAY_VARS)
1281@@ -375,10 +376,17 @@
1282        }
1283 #  endif
1284 #endif
1285+#if 0
1286       else if (legal_identifier (name))
1287+#else
1288+      else
1289+#endif
1290        {
1291          temp_var = bind_variable (name, string, 0);
1292-         VSETATTR (temp_var, (att_exported | att_imported));
1293+         if (legal_identifier (name))
1294+           VSETATTR (temp_var, (att_exported | att_imported));
1295+         else
1296+           VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
1297          array_needs_making = 1;
1298        }
1299 
1300@@ -2209,7 +2217,7 @@
1301        }
1302       else if (assoc_p (entry))
1303        {
1304-         assoc_insert (assoc_cell (entry), "0", newval);
1305+         assoc_insert (assoc_cell (entry), savestring ("0"), newval);
1306          free (newval);
1307        }
1308       else
1309@@ -3082,6 +3090,16 @@
1310   return (invisible_p (var) == 0 && exported_p (var));
1311 }
1312 
1313+/* Candidate variables for the export environment are either valid variables
1314+   with the export attribute or invalid variables inherited from the initial
1315+   environment and simply passed through. */
1316+static int
1317+export_environment_candidate (var)
1318+     SHELL_VAR *var;
1319+{
1320+  return (exported_p (var) && (invisible_p (var) == 0 || imported_p (var)));
1321+}
1322+
1323 /* Return non-zero if VAR is a local variable in the current context and
1324    is exported. */
1325 static int
1326@@ -3438,7 +3456,11 @@
1327   char **list;
1328   SHELL_VAR **vars;
1329 
1330+#if 0
1331   vars = map_over (visible_and_exported, vcxt);
1332+#else
1333+  vars = map_over (export_environment_candidate, vcxt);
1334+#endif
1335 
1336   if (vars == 0)
1337     return (char **)NULL;
Note: See TracBrowser for help on using the repository browser.