source: patches/bash-4.0-branch_update-5.patch @ 140d857

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

Updated Bash Update Patch to 5

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