source: patches/bash-4.2-branch_update-4.patch @ 9f5b4d49

clfs-2.1clfs-3.0.0-systemdclfs-3.0.0-sysvinitsystemdsysvinit
Last change on this file since 9f5b4d49 was eb3c388, checked in by Jonathan Norman <jon@…>, 12 years ago

Updated bash and vim branch update patches to -4

  • Property mode set to 100644
File size: 41.9 KB
RevLine 
[eb3c388]1Submitted By: Jonathan Norman (jonathan at bluesquarelinux.co.uk)
2Date: 06-03-2012
3Initial Package Version: 4.2
4Origin: Upstream
5Upstream Status: Applied
6Description: Contains all upstream patches up to 4.2-029
7
8diff -Naur bash-4.2.orig/assoc.c bash-4.2/assoc.c
9--- bash-4.2.orig/assoc.c       2009-08-06 00:19:40.000000000 +0000
10+++ bash-4.2/assoc.c    2012-06-03 18:59:11.431067287 +0000
11@@ -77,6 +77,11 @@
12   b = hash_search (key, hash, HASH_CREATE);
13   if (b == 0)
14     return -1;
15+  /* If we are overwriting an existing element's value, we're not going to
16+     use the key.  Nothing in the array assignment code path frees the key
17+     string, so we can free it here to avoid a memory leak. */
18+  if (b->key != key)
19+    free (key);
20   FREE (b->data);
21   b->data = value ? savestring (value) : (char *)0;
22   return (0);
23diff -Naur bash-4.2.orig/bashline.c bash-4.2/bashline.c
24--- bash-4.2.orig/bashline.c    2011-01-16 20:32:47.000000000 +0000
25+++ bash-4.2/bashline.c 2012-06-03 18:59:34.467691069 +0000
26@@ -121,6 +121,9 @@
27 static int filename_completion_ignore __P((char **));
28 static int bash_push_line __P((void));
29 
30+static rl_icppfunc_t *save_directory_hook __P((void));
31+static void reset_directory_hook __P((rl_icppfunc_t *));
32+
33 static void cleanup_expansion_error __P((void));
34 static void maybe_make_readline_line __P((char *));
35 static void set_up_new_line __P((char *));
36@@ -243,10 +246,17 @@
37 /* Perform spelling correction on directory names during word completion */
38 int dircomplete_spelling = 0;
39 
40+/* Expand directory names during word/filename completion. */
41+int dircomplete_expand = 0;
42+int dircomplete_expand_relpath = 0;
43+
44 static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:";
45 static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:";
46 /* )) */
47 
48+static const char *default_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~";        /*}*/
49+static char *custom_filename_quote_characters = 0;
50+
51 static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL;
52 
53 static int dot_in_path = 0;
54@@ -501,7 +511,7 @@
55 
56   /* Tell the completer that we might want to follow symbolic links or
57      do other expansion on directory names. */
58-  rl_directory_rewrite_hook = bash_directory_completion_hook;
59+  set_directory_hook ();
60 
61   rl_filename_rewrite_hook = bash_filename_rewrite_hook;
62 
63@@ -529,7 +539,7 @@
64   enable_hostname_completion (perform_hostname_completion);
65 
66   /* characters that need to be quoted when appearing in filenames. */
67-  rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~";      /*}*/
68+  rl_filename_quote_characters = default_filename_quote_characters;
69 
70   rl_filename_quoting_function = bash_quote_filename;
71   rl_filename_dequoting_function = bash_dequote_filename;
72@@ -564,8 +574,10 @@
73   tilde_initialize ();
74   rl_attempted_completion_function = attempt_shell_completion;
75   rl_completion_entry_function = NULL;
76-  rl_directory_rewrite_hook = bash_directory_completion_hook;
77   rl_ignore_some_completions_function = filename_completion_ignore;
78+  rl_filename_quote_characters = default_filename_quote_characters;
79+
80+  set_directory_hook ();
81 }
82 
83 /* Contains the line to push into readline. */
84@@ -1279,6 +1291,9 @@
85   matches = (char **)NULL;
86   rl_ignore_some_completions_function = filename_completion_ignore;
87 
88+  rl_filename_quote_characters = default_filename_quote_characters;
89+  set_directory_hook ();
90+
91   /* Determine if this could be a command word.  It is if it appears at
92      the start of the line (ignoring preceding whitespace), or if it
93      appears after a character that separates commands.  It cannot be a
94@@ -1591,6 +1606,12 @@
95            }
96          else
97            {
98+            if (dircomplete_expand && dot_or_dotdot (filename_hint))
99+               {
100+                 dircomplete_expand = 0;
101+                 set_directory_hook ();
102+                 dircomplete_expand = 1;
103+               }
104              mapping_over = 4;
105              goto inner;
106            }
107@@ -1791,6 +1812,9 @@
108 
109  inner:
110   val = rl_filename_completion_function (filename_hint, istate);
111+  if (mapping_over == 4 && dircomplete_expand)
112+    set_directory_hook ();
113+
114   istate = 1;
115 
116   if (val == 0)
117@@ -2693,6 +2717,52 @@
118   return conv;
119 }
120 
121+/* Functions to save and restore the appropriate directory hook */
122+/* This is not static so the shopt code can call it */
123+void
124+set_directory_hook ()
125+{
126+  if (dircomplete_expand)
127+    {
128+      rl_directory_completion_hook = bash_directory_completion_hook;
129+      rl_directory_rewrite_hook = (rl_icppfunc_t *)0;
130+    }
131+  else
132+    {
133+      rl_directory_rewrite_hook = bash_directory_completion_hook;
134+      rl_directory_completion_hook = (rl_icppfunc_t *)0;
135+    }
136+}
137+
138+static rl_icppfunc_t *
139+save_directory_hook ()
140+{
141+  rl_icppfunc_t *ret;
142+
143+  if (dircomplete_expand)
144+    {
145+      ret = rl_directory_completion_hook;
146+      rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
147+    }
148+  else
149+    {
150+      ret = rl_directory_rewrite_hook;
151+      rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
152+    }
153+
154+  return ret;
155+}
156+
157+static void
158+restore_directory_hook (hookf)
159+     rl_icppfunc_t *hookf;
160+{
161+  if (dircomplete_expand)
162+    rl_directory_completion_hook = hookf;
163+  else
164+    rl_directory_rewrite_hook = hookf;
165+}
166+
167 /* Handle symbolic link references and other directory name
168    expansions while hacking completion.  This should return 1 if it modifies
169    the DIRNAME argument, 0 otherwise.  It should make sure not to modify
170@@ -2702,20 +2772,31 @@
171      char **dirname;
172 {
173   char *local_dirname, *new_dirname, *t;
174-  int return_value, should_expand_dirname;
175+  int return_value, should_expand_dirname, nextch, closer;
176   WORD_LIST *wl;
177   struct stat sb;
178 
179-  return_value = should_expand_dirname = 0;
180+  return_value = should_expand_dirname = nextch = closer = 0;
181   local_dirname = *dirname;
182 
183-  if (mbschr (local_dirname, '$'))
184-    should_expand_dirname = 1;
185+  if (t = mbschr (local_dirname, '$'))
186+    {
187+      should_expand_dirname = '$';
188+      nextch = t[1];
189+      /* Deliberately does not handle the deprecated $[...] arithmetic
190+        expansion syntax */
191+      if (nextch == '(')
192+       closer = ')';
193+      else if (nextch == '{')
194+       closer = '}';
195+      else
196+       nextch = 0;
197+    }
198   else
199     {
200       t = mbschr (local_dirname, '`');
201       if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0)
202-       should_expand_dirname = 1;
203+       should_expand_dirname = '`';
204     }
205 
206 #if defined (HAVE_LSTAT)
207@@ -2739,6 +2820,23 @@
208          free (new_dirname);
209          dispose_words (wl);
210          local_dirname = *dirname;
211+         /* XXX - change rl_filename_quote_characters here based on
212+            should_expand_dirname/nextch/closer.  This is the only place
213+            custom_filename_quote_characters is modified. */
214+         if (rl_filename_quote_characters && *rl_filename_quote_characters)
215+           {
216+             int i, j, c;
217+             i = strlen (default_filename_quote_characters);
218+             custom_filename_quote_characters = xrealloc (custom_filename_quote_characters, i+1);
219+             for (i = j = 0; c = default_filename_quote_characters[i]; i++)
220+               {
221+                 if (c == should_expand_dirname || c == nextch || c == closer)
222+                   continue;
223+                 custom_filename_quote_characters[j++] = c;
224+               }
225+             custom_filename_quote_characters[j] = '\0';
226+             rl_filename_quote_characters = custom_filename_quote_characters;
227+           }
228        }
229       else
230        {
231@@ -2758,11 +2856,31 @@
232       local_dirname = *dirname = new_dirname;
233     }
234 
235+  /* no_symbolic_links == 0 -> use (default) logical view of the file system.
236+     local_dirname[0] == '.' && local_dirname[1] == '/' means files in the
237+     current directory (./).
238+     local_dirname[0] == '.' && local_dirname[1] == 0 means relative pathnames
239+     in the current directory (e.g., lib/sh).
240+     XXX - should we do spelling correction on these? */
241+
242+  /* This is test as it was in bash-4.2: skip relative pathnames in current
243+     directory.  Change test to
244+      (local_dirname[0] != '.' || (local_dirname[1] && local_dirname[1] != '/'))
245+     if we want to skip paths beginning with ./ also. */
246   if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1]))
247     {
248       char *temp1, *temp2;
249       int len1, len2;
250 
251+      /* If we have a relative path
252+               (local_dirname[0] != '/' && local_dirname[0] != '.')
253+        that is canonical after appending it to the current directory, then
254+               temp1 = temp2+'/'
255+        That is,
256+               strcmp (temp1, temp2) == 0
257+        after adding a slash to temp2 below.  It should be safe to not
258+        change those.
259+      */
260       t = get_working_directory ("symlink-hook");
261       temp1 = make_absolute (local_dirname, t);
262       free (t);
263@@ -2797,7 +2915,15 @@
264              temp2[len2 + 1] = '\0';
265            }
266        }
267-      return_value |= STREQ (local_dirname, temp2) == 0;
268+
269+      /* dircomplete_expand_relpath == 0 means we want to leave relative
270+        pathnames that are unchanged by canonicalization alone.
271+        *local_dirname != '/' && *local_dirname != '.' == relative pathname
272+        (consistent with general.c:absolute_pathname())
273+        temp1 == temp2 (after appending a slash to temp2) means the pathname
274+        is not changed by canonicalization as described above. */
275+      if (dircomplete_expand_relpath || ((local_dirname[0] != '/' && local_dirname[0] != '.') && STREQ (temp1, temp2) == 0))
276+       return_value |= STREQ (local_dirname, temp2) == 0;
277       free (local_dirname);
278       *dirname = temp2;
279       free (temp1);
280@@ -3002,12 +3128,13 @@
281 
282   orig_func = rl_completion_entry_function;
283   orig_attempt_func = rl_attempted_completion_function;
284-  orig_dir_func = rl_directory_rewrite_hook;
285   orig_ignore_func = rl_ignore_some_completions_function;
286   orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
287+
288+  orig_dir_func = save_directory_hook ();
289+
290   rl_completion_entry_function = rl_filename_completion_function;
291   rl_attempted_completion_function = (rl_completion_func_t *)NULL;
292-  rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
293   rl_ignore_some_completions_function = filename_completion_ignore;
294   rl_completer_word_break_characters = " \t\n\"\'";
295 
296@@ -3015,10 +3142,11 @@
297 
298   rl_completion_entry_function = orig_func;
299   rl_attempted_completion_function = orig_attempt_func;
300-  rl_directory_rewrite_hook = orig_dir_func;
301   rl_ignore_some_completions_function = orig_ignore_func;
302   rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
303 
304+  restore_directory_hook (orig_dir_func);
305+
306   return r;
307 }
308 
309diff -Naur bash-4.2.orig/bashline.h bash-4.2/bashline.h
310--- bash-4.2.orig/bashline.h    2009-01-04 19:32:22.000000000 +0000
311+++ bash-4.2/bashline.h 2012-06-03 18:59:34.467691069 +0000
312@@ -33,10 +33,15 @@
313 extern void bashline_reinitialize __P((void));
314 extern int bash_re_edit __P((char *));
315 
316+extern void bashline_set_event_hook __P((void));
317+extern void bashline_reset_event_hook __P((void));
318+
319 extern int bind_keyseq_to_unix_command __P((char *));
320 
321 extern char **bash_default_completion __P((const char *, int, int, int, int));
322 
323+void set_directory_hook __P((void));
324+
325 /* Used by programmable completion code. */
326 extern char *command_word_completion_function __P((const char *, int));
327 extern char *bash_groupname_completion_function __P((const char *, int));
328diff -Naur bash-4.2.orig/builtins/declare.def bash-4.2/builtins/declare.def
329--- bash-4.2.orig/builtins/declare.def  2010-05-30 22:25:21.000000000 +0000
330+++ bash-4.2/builtins/declare.def       2012-06-03 18:59:21.655344143 +0000
331@@ -513,6 +513,11 @@
332              *subscript_start = '[';   /* ] */
333              var = assign_array_element (name, value, 0);      /* XXX - not aflags */
334              *subscript_start = '\0';
335+             if (var == 0)     /* some kind of assignment error */
336+               {
337+                 assign_error++;
338+                 NEXT_VARIABLE ();
339+               }
340            }
341          else if (simple_array_assign)
342            {
343diff -Naur bash-4.2.orig/builtins/fc.def bash-4.2/builtins/fc.def
344--- bash-4.2.orig/builtins/fc.def       2010-05-30 22:25:38.000000000 +0000
345+++ bash-4.2/builtins/fc.def    2012-06-03 18:59:08.910999047 +0000
346@@ -304,7 +304,7 @@
347   last_hist = i - rh - hist_last_line_added;
348 
349   /* XXX */
350-  if (saved_command_line_count > 0 && i == last_hist && hlist[last_hist] == 0)
351+  if (i == last_hist && hlist[last_hist] == 0)
352     while (last_hist >= 0 && hlist[last_hist] == 0)
353       last_hist--;
354   if (last_hist < 0)
355@@ -475,7 +475,7 @@
356      HIST_ENTRY **hlist;
357 {
358   int sign, n, clen, rh;
359-  register int i, j;
360+  register int i, j, last_hist;
361   register char *s;
362 
363   sign = 1;
364@@ -495,7 +495,15 @@
365      has been enabled (interactive or not) should use it in the last_hist
366      calculation as if it were on. */
367   rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
368-  i -= rh + hist_last_line_added;
369+  last_hist = i - rh - hist_last_line_added;
370+
371+  if (i == last_hist && hlist[last_hist] == 0)
372+    while (last_hist >= 0 && hlist[last_hist] == 0)
373+      last_hist--;
374+  if (last_hist < 0)
375+    return (-1);
376+
377+  i = last_hist;
378 
379   /* No specification defaults to most recent command. */
380   if (command == NULL)
381diff -Naur bash-4.2.orig/builtins/printf.def bash-4.2/builtins/printf.def
382--- bash-4.2.orig/builtins/printf.def   2010-11-23 15:02:55.000000000 +0000
383+++ bash-4.2/builtins/printf.def        2012-06-03 18:59:27.971515171 +0000
384@@ -255,6 +255,8 @@
385 #endif
386            {
387              vflag = 1;
388+             if (vbsize == 0)
389+               vbuf = xmalloc (vbsize = 16);
390              vblen = 0;
391              if (vbuf)
392                vbuf[0] = 0;
393@@ -465,6 +467,9 @@
394                  secs = shell_start_time;      /* roughly $SECONDS */
395                else
396                  secs = arg;
397+#if defined (HAVE_TZSET)
398+               sv_tz ("TZ");           /* XXX -- just make sure */
399+#endif
400                tm = localtime (&secs);
401                n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
402                free (timefmt);
403diff -Naur bash-4.2.orig/builtins/read.def bash-4.2/builtins/read.def
404--- bash-4.2.orig/builtins/read.def     2011-01-04 16:43:36.000000000 +0000
405+++ bash-4.2/builtins/read.def  2012-06-03 18:59:24.187412704 +0000
406@@ -642,6 +642,12 @@
407          xfree (input_string);
408          return EXECUTION_FAILURE;     /* readonly or noassign */
409        }
410+      if (assoc_p (var))
411+       {
412+          builtin_error (_("%s: cannot convert associative to indexed array"), arrayname);
413+         xfree (input_string);
414+         return EXECUTION_FAILURE;     /* existing associative array */
415+       }
416       array_flush (array_cell (var));
417 
418       alist = list_string (input_string, ifs_chars, 0);
419@@ -731,7 +737,7 @@
420              xfree (t1);
421            }
422          else
423-           var = bind_read_variable (varname, t);
424+           var = bind_read_variable (varname, t ? t : "");
425        }
426       else
427        {
428@@ -792,7 +798,7 @@
429       xfree (t);
430     }
431   else
432-    var = bind_read_variable (list->word->word, input_string);
433+    var = bind_read_variable (list->word->word, input_string ? input_string : "");
434 
435   if (var)
436     {
437diff -Naur bash-4.2.orig/builtins/shopt.def bash-4.2/builtins/shopt.def
438--- bash-4.2.orig/builtins/shopt.def    2010-07-03 02:42:44.000000000 +0000
439+++ bash-4.2/builtins/shopt.def 2012-06-03 18:59:34.467691069 +0000
440@@ -61,6 +61,10 @@
441 #include "common.h"
442 #include "bashgetopt.h"
443 
444+#if defined (READLINE)
445+#  include "../bashline.h"
446+#endif
447+
448 #if defined (HISTORY)
449 #  include "../bashhist.h"
450 #endif
451@@ -94,7 +98,7 @@
452 extern int hist_verify, history_reediting, perform_hostname_completion;
453 extern int no_empty_command_completion;
454 extern int force_fignore;
455-extern int dircomplete_spelling;
456+extern int dircomplete_spelling, dircomplete_expand;
457 
458 extern int enable_hostname_completion __P((int));
459 #endif
460@@ -121,6 +125,10 @@
461 static int set_restricted_shell __P((char *, int));
462 #endif
463 
464+#if defined (READLINE)
465+static int shopt_set_complete_direxpand __P((char *, int));
466+#endif
467+
468 static int shopt_login_shell;
469 static int shopt_compat31;
470 static int shopt_compat32;
471@@ -150,6 +158,7 @@
472   { "compat40", &shopt_compat40, set_compatibility_level },
473   { "compat41", &shopt_compat41, set_compatibility_level },
474 #if defined (READLINE)
475+  { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
476   { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
477 #endif
478   { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
479@@ -535,6 +544,17 @@
480   return 0;
481 }
482 
483+#if defined (READLINE)
484+static int
485+shopt_set_complete_direxpand (option_name, mode)
486+     char *option_name;
487+     int mode;
488+{
489+  set_directory_hook ();
490+  return 0;
491+}
492+#endif
493+
494 #if defined (RESTRICTED_SHELL)
495 /* Don't allow the value of restricted_shell to be modified. */
496 
497diff -Naur bash-4.2.orig/command.h bash-4.2/command.h
498--- bash-4.2.orig/command.h     2010-08-02 23:36:51.000000000 +0000
499+++ bash-4.2/command.h  2012-06-03 18:59:29.227549180 +0000
500@@ -97,6 +97,7 @@
501 #define W_HASCTLESC    0x200000        /* word contains literal CTLESC characters */
502 #define W_ASSIGNASSOC  0x400000        /* word looks like associative array assignment */
503 #define W_ARRAYIND     0x800000        /* word is an array index being expanded */
504+#define W_ASSNGLOBAL   0x1000000       /* word is a global assignment to declare (declare/typeset -g) */
505 
506 /* Possible values for subshell_environment */
507 #define SUBSHELL_ASYNC 0x01    /* subshell caused by `command &' */
508diff -Naur bash-4.2.orig/doc/bash.1 bash-4.2/doc/bash.1
509--- bash-4.2.orig/doc/bash.1    2011-01-16 20:31:39.000000000 +0000
510+++ bash-4.2/doc/bash.1 2012-06-03 18:59:34.471691177 +0000
511@@ -8948,6 +8948,16 @@
512 quoted.  This is the behavior of posix mode through version 4.1.
513 The default bash behavior remains as in previous versions.
514 .TP 8
515+.B direxpand
516+If set,
517+.B bash
518+replaces directory names with the results of word expansion when performing
519+filename completion.  This changes the contents of the readline editing
520+buffer.
521+If not set,
522+.B bash
523+attempts to preserve what the user typed.
524+.TP 8
525 .B dirspell
526 If set,
527 .B bash
528diff -Naur bash-4.2.orig/doc/bashref.texi bash-4.2/doc/bashref.texi
529--- bash-4.2.orig/doc/bashref.texi      2011-01-16 20:31:57.000000000 +0000
530+++ bash-4.2/doc/bashref.texi   2012-06-03 18:59:34.475691285 +0000
531@@ -4535,6 +4535,13 @@
532 quoted.  This is the behavior of @sc{posix} mode through version 4.1.
533 The default Bash behavior remains as in previous versions.
534 
535+@item direxpand
536+If set, Bash
537+replaces directory names with the results of word expansion when performing
538+filename completion.  This changes the contents of the readline editing
539+buffer.
540+If not set, Bash attempts to preserve what the user typed.
541+
542 @item dirspell
543 If set, Bash
544 attempts spelling correction on directory names during word completion
545diff -Naur bash-4.2.orig/error.c bash-4.2/error.c
546--- bash-4.2.orig/error.c       2009-08-22 02:31:31.000000000 +0000
547+++ bash-4.2/error.c    2012-06-03 18:59:26.707480942 +0000
548@@ -200,7 +200,11 @@
549 
550   va_end (args);
551   if (exit_immediately_on_error)
552-    exit_shell (1);
553+    {
554+      if (last_command_exit_value == 0)
555+       last_command_exit_value = 1;
556+      exit_shell (last_command_exit_value);
557+    }
558 }
559 
560 void
561diff -Naur bash-4.2.orig/execute_cmd.c bash-4.2/execute_cmd.c
562--- bash-4.2.orig/execute_cmd.c 2011-02-09 22:32:25.000000000 +0000
563+++ bash-4.2/execute_cmd.c      2012-06-03 18:59:30.491583407 +0000
564@@ -2196,6 +2196,7 @@
565   if (ignore_return && cmd)
566     cmd->flags |= CMD_IGNORE_RETURN;
567 
568+#if defined (JOB_CONTROL)
569   lastpipe_flag = 0;
570   begin_unwind_frame ("lastpipe-exec");
571   lstdin = -1;
572@@ -2204,7 +2205,7 @@
573      current shell environment. */
574   if (lastpipe_opt && job_control == 0 && asynchronous == 0 && pipe_out == NO_PIPE && prev > 0)
575     {
576-      lstdin = move_to_high_fd (0, 0, 255);
577+      lstdin = move_to_high_fd (0, 1, -1);
578       if (lstdin > 0)
579        {
580          do_piping (prev, pipe_out);
581@@ -2215,15 +2216,19 @@
582          lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL);    /* XXX */
583          add_unwind_protect (lastpipe_cleanup, lastpipe_jid);
584        }
585-      cmd->flags |= CMD_LASTPIPE;
586+      if (cmd)
587+       cmd->flags |= CMD_LASTPIPE;
588     }   
589   if (prev >= 0)
590     add_unwind_protect (close, prev);
591+#endif
592 
593   exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close);
594 
595+#if defined (JOB_CONTROL)
596   if (lstdin > 0)
597     restore_stdin (lstdin);
598+#endif
599 
600   if (prev >= 0)
601     close (prev);
602@@ -2246,7 +2251,9 @@
603       unfreeze_jobs_list ();
604     }
605 
606+#if defined (JOB_CONTROL)
607   discard_unwind_frame ("lastpipe-exec");
608+#endif
609 
610   return (exec_result);
611 }
612@@ -3575,13 +3582,13 @@
613 {
614   WORD_LIST *w;
615   struct builtin *b;
616-  int assoc;
617+  int assoc, global;
618 
619   if (words == 0)
620     return;
621 
622   b = 0;
623-  assoc = 0;
624+  assoc = global = 0;
625 
626   for (w = words; w; w = w->next)
627     if (w->word->flags & W_ASSIGNMENT)
628@@ -3598,12 +3605,17 @@
629 #if defined (ARRAY_VARS)
630        if (assoc)
631          w->word->flags |= W_ASSIGNASSOC;
632+       if (global)
633+         w->word->flags |= W_ASSNGLOBAL;
634 #endif
635       }
636 #if defined (ARRAY_VARS)
637     /* Note that we saw an associative array option to a builtin that takes
638        assignment statements.  This is a bit of a kludge. */
639-    else if (w->word->word[0] == '-' && strchr (w->word->word, 'A'))
640+    else if (w->word->word[0] == '-' && (strchr (w->word->word+1, 'A') || strchr (w->word->word+1, 'g')))
641+#else
642+    else if (w->word->word[0] == '-' && strchr (w->word->word+1, 'g'))
643+#endif
644       {
645        if (b == 0)
646          {
647@@ -3613,10 +3625,11 @@
648            else if (b && (b->flags & ASSIGNMENT_BUILTIN))
649              words->word->flags |= W_ASSNBLTIN;
650          }
651-       if (words->word->flags & W_ASSNBLTIN)
652+       if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'A'))
653          assoc = 1;
654+       if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'g'))
655+         global = 1;
656       }
657-#endif
658 }
659 
660 /* Return 1 if the file found by searching $PATH for PATHNAME, defaulting
661diff -Naur bash-4.2.orig/expr.c bash-4.2/expr.c
662--- bash-4.2.orig/expr.c        2010-12-21 16:12:13.000000000 +0000
663+++ bash-4.2/expr.c     2012-06-03 18:59:16.535205499 +0000
664@@ -476,19 +476,23 @@
665 
666       if (special)
667        {
668+         if ((op == DIV || op == MOD) && value == 0)
669+           {
670+             if (noeval == 0)
671+               evalerror (_("division by 0"));
672+             else
673+               value = 1;
674+           }
675+
676          switch (op)
677            {
678            case MUL:
679              lvalue *= value;
680              break;
681            case DIV:
682-             if (value == 0)
683-               evalerror (_("division by 0"));
684              lvalue /= value;
685              break;
686            case MOD:
687-             if (value == 0)
688-               evalerror (_("division by 0"));
689              lvalue %= value;
690              break;
691            case PLUS:
692@@ -804,7 +808,12 @@
693       val2 = exppower ();
694 
695       if (((op == DIV) || (op == MOD)) && (val2 == 0))
696-       evalerror (_("division by 0"));
697+       {
698+         if (noeval == 0)
699+           evalerror (_("division by 0"));
700+         else
701+           val2 = 1;
702+       }
703 
704       if (op == MUL)
705        val1 *= val2;
706diff -Naur bash-4.2.orig/lib/glob/gmisc.c bash-4.2/lib/glob/gmisc.c
707--- bash-4.2.orig/lib/glob/gmisc.c      2011-02-05 21:11:17.000000000 +0000
708+++ bash-4.2/lib/glob/gmisc.c   2012-06-03 18:59:01.258791836 +0000
709@@ -77,8 +77,8 @@
710      wchar_t *wpat;
711      size_t wmax;
712 {
713-  wchar_t wc, *wbrack;
714-  int matlen, t, in_cclass, in_collsym, in_equiv;
715+  wchar_t wc;
716+  int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
717 
718   if (*wpat == 0)
719     return (0);
720@@ -118,58 +118,80 @@
721          break;
722        case L'[':
723          /* scan for ending `]', skipping over embedded [:...:] */
724-         wbrack = wpat;
725+         bracklen = 1;
726          wc = *wpat++;
727          do
728            {
729              if (wc == 0)
730                {
731-                 matlen += wpat - wbrack - 1;  /* incremented below */
732-                 break;
733+                 wpat--;                       /* back up to NUL */
734+                 matlen += bracklen;
735+                 goto bad_bracket;
736                }
737              else if (wc == L'\\')
738                {
739-                 wc = *wpat++;
740-                 if (*wpat == 0)
741-                   break;
742+                 /* *wpat == backslash-escaped character */
743+                 bracklen++;
744+                 /* If the backslash or backslash-escape ends the string,
745+                    bail.  The ++wpat skips over the backslash escape */
746+                 if (*wpat == 0 || *++wpat == 0)
747+                   {
748+                     matlen += bracklen;
749+                     goto bad_bracket;
750+                   }
751                }
752              else if (wc == L'[' && *wpat == L':')     /* character class */
753                {
754                  wpat++;
755+                 bracklen++;
756                  in_cclass = 1;
757                }
758              else if (in_cclass && wc == L':' && *wpat == L']')
759                {
760                  wpat++;
761+                 bracklen++;
762                  in_cclass = 0;
763                }
764              else if (wc == L'[' && *wpat == L'.')     /* collating symbol */
765                {
766                  wpat++;
767+                 bracklen++;
768                  if (*wpat == L']')    /* right bracket can appear as collating symbol */
769-                   wpat++;
770+                   {
771+                     wpat++;
772+                     bracklen++;
773+                   }
774                  in_collsym = 1;
775                }
776              else if (in_collsym && wc == L'.' && *wpat == L']')
777                {
778                  wpat++;
779+                 bracklen++;
780                  in_collsym = 0;
781                }
782              else if (wc == L'[' && *wpat == L'=')     /* equivalence class */
783                {
784                  wpat++;
785+                 bracklen++;
786                  if (*wpat == L']')    /* right bracket can appear as equivalence class */
787-                   wpat++;
788+                   {
789+                     wpat++;
790+                     bracklen++;
791+                   }
792                  in_equiv = 1;
793                }
794              else if (in_equiv && wc == L'=' && *wpat == L']')
795                {
796                  wpat++;
797+                 bracklen++;
798                  in_equiv = 0;
799                }
800+             else
801+               bracklen++;
802            }
803          while ((wc = *wpat++) != L']');
804          matlen++;             /* bracket expression can only match one char */
805+bad_bracket:
806          break;
807        }
808     }
809@@ -213,8 +235,8 @@
810      char *pat;
811      size_t max;
812 {
813-  char c, *brack;
814-  int matlen, t, in_cclass, in_collsym, in_equiv;
815+  char c;
816+  int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
817 
818   if (*pat == 0)
819     return (0);
820@@ -254,58 +276,80 @@
821          break;
822        case '[':
823          /* scan for ending `]', skipping over embedded [:...:] */
824-         brack = pat;
825+         bracklen = 1;
826          c = *pat++;
827          do
828            {
829              if (c == 0)
830                {
831-                 matlen += pat - brack - 1;    /* incremented below */
832-                 break;
833+                 pat--;                        /* back up to NUL */
834+                 matlen += bracklen;
835+                 goto bad_bracket;
836                }
837              else if (c == '\\')
838                {
839-                 c = *pat++;
840-                 if (*pat == 0)
841-                   break;
842+                 /* *pat == backslash-escaped character */
843+                 bracklen++;
844+                 /* If the backslash or backslash-escape ends the string,
845+                    bail.  The ++pat skips over the backslash escape */
846+                 if (*pat == 0 || *++pat == 0)
847+                   {
848+                     matlen += bracklen;
849+                     goto bad_bracket;
850+                   }
851                }
852              else if (c == '[' && *pat == ':') /* character class */
853                {
854                  pat++;
855+                 bracklen++;
856                  in_cclass = 1;
857                }
858              else if (in_cclass && c == ':' && *pat == ']')
859                {
860                  pat++;
861+                 bracklen++;
862                  in_cclass = 0;
863                }
864              else if (c == '[' && *pat == '.') /* collating symbol */
865                {
866                  pat++;
867+                 bracklen++;
868                  if (*pat == ']')      /* right bracket can appear as collating symbol */
869-                   pat++;
870+                   {
871+                     pat++;
872+                     bracklen++;
873+                   }
874                  in_collsym = 1;
875                }
876              else if (in_collsym && c == '.' && *pat == ']')
877                {
878                  pat++;
879+                 bracklen++;
880                  in_collsym = 0;
881                }
882              else if (c == '[' && *pat == '=') /* equivalence class */
883                {
884                  pat++;
885+                 bracklen++;
886                  if (*pat == ']')      /* right bracket can appear as equivalence class */
887-                   pat++;
888+                   {
889+                     pat++;
890+                     bracklen++;
891+                   }
892                  in_equiv = 1;
893                }
894              else if (in_equiv && c == '=' && *pat == ']')
895                {
896                  pat++;
897+                 bracklen++;
898                  in_equiv = 0;
899                }
900+             else
901+               bracklen++;
902            }
903          while ((c = *pat++) != ']');
904          matlen++;             /* bracket expression can only match one char */
905+bad_bracket:
906          break;
907        }
908     }
909diff -Naur bash-4.2.orig/lib/readline/callback.c bash-4.2/lib/readline/callback.c
910--- bash-4.2.orig/lib/readline/callback.c       2010-06-06 16:18:58.000000000 +0000
911+++ bash-4.2/lib/readline/callback.c    2012-06-03 18:58:59.942756197 +0000
912@@ -148,6 +148,9 @@
913          eof = _rl_vi_domove_callback (_rl_vimvcxt);
914          /* Should handle everything, including cleanup, numeric arguments,
915             and turning off RL_STATE_VIMOTION */
916+         if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
917+           _rl_internal_char_cleanup ();
918+
919          return;
920        }
921 #endif
922diff -Naur bash-4.2.orig/lib/readline/vi_mode.c bash-4.2/lib/readline/vi_mode.c
923--- bash-4.2.orig/lib/readline/vi_mode.c        2010-11-21 00:51:39.000000000 +0000
924+++ bash-4.2/lib/readline/vi_mode.c     2012-06-03 18:58:59.938756089 +0000
925@@ -1114,7 +1114,7 @@
926       rl_beg_of_line (1, c);
927       _rl_vi_last_motion = c;
928       RL_UNSETSTATE (RL_STATE_VIMOTION);
929-      return (0);
930+      return (vidomove_dispatch (m));
931     }
932 #if defined (READLINE_CALLBACKS)
933   /* XXX - these need to handle rl_universal_argument bindings */
934diff -Naur bash-4.2.orig/lib/sh/zread.c bash-4.2/lib/sh/zread.c
935--- bash-4.2.orig/lib/sh/zread.c        2009-03-02 13:54:45.000000000 +0000
936+++ bash-4.2/lib/sh/zread.c     2012-06-03 18:59:25.447446823 +0000
937@@ -160,14 +160,13 @@
938 zsyncfd (fd)
939      int fd;
940 {
941-  off_t off;
942-  int r;
943+  off_t off, r;
944 
945   off = lused - lind;
946   r = 0;
947   if (off > 0)
948     r = lseek (fd, -off, SEEK_CUR);
949 
950-  if (r >= 0)
951+  if (r != -1)
952     lused = lind = 0;
953 }
954diff -Naur bash-4.2.orig/parse.y bash-4.2/parse.y
955--- bash-4.2.orig/parse.y       2011-01-02 20:48:11.000000000 +0000
956+++ bash-4.2/parse.y    2012-06-03 18:59:17.827240486 +0000
957@@ -2499,7 +2499,7 @@
958         We do this only if it is time to do so. Notice that only here
959         is the mail alarm reset; nothing takes place in check_mail ()
960         except the checking of mail.  Please don't change this. */
961-      if (prompt_is_ps1 && time_to_check_mail ())
962+      if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ())
963        {
964          check_mail ();
965          reset_mail_timer ();
966@@ -3842,6 +3842,7 @@
967      int flags;
968 {
969   sh_parser_state_t ps;
970+  sh_input_line_state_t ls;
971   int orig_ind, nc, sflags;
972   char *ret, *s, *ep, *ostring;
973 
974@@ -3849,10 +3850,12 @@
975   orig_ind = *indp;
976   ostring = string;
977 
978+/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/
979   sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
980   if (flags & SX_NOLONGJMP)
981     sflags |= SEVAL_NOLONGJMP;
982   save_parser_state (&ps);
983+  save_input_line_state (&ls);
984 
985   /*(*/
986   parser_state |= PST_CMDSUBST|PST_EOFTOKEN;   /* allow instant ')' */ /*(*/
987@@ -3861,6 +3864,8 @@
988 
989   restore_parser_state (&ps);
990   reset_parser ();
991+  /* reset_parser clears shell_input_line and associated variables */
992+  restore_input_line_state (&ls);
993   if (interactive)
994     token_to_read = 0;
995 
996@@ -5135,6 +5140,9 @@
997            case 'A':
998              /* Make the current time/date into a string. */
999              (void) time (&the_time);
1000+#if defined (HAVE_TZSET)
1001+             sv_tz ("TZ");             /* XXX -- just make sure */
1002+#endif
1003              tm = localtime (&the_time);
1004 
1005              if (c == 'd')
1006@@ -5905,6 +5913,12 @@
1007   ps->expand_aliases = expand_aliases;
1008   ps->echo_input_at_read = echo_input_at_read;
1009 
1010+  ps->token = token;
1011+  ps->token_buffer_size = token_buffer_size;
1012+  /* Force reallocation on next call to read_token_word */
1013+  token = 0;
1014+  token_buffer_size = 0;
1015+
1016   return (ps);
1017 }
1018 
1019@@ -5946,6 +5960,42 @@
1020 
1021   expand_aliases = ps->expand_aliases;
1022   echo_input_at_read = ps->echo_input_at_read;
1023+
1024+  FREE (token);
1025+  token = ps->token;
1026+  token_buffer_size = ps->token_buffer_size;
1027+}
1028+
1029+sh_input_line_state_t *
1030+save_input_line_state (ls)
1031+     sh_input_line_state_t *ls;
1032+{
1033+  if (ls == 0)
1034+    ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
1035+  if (ls == 0)
1036+    return ((sh_input_line_state_t *)NULL);
1037+
1038+  ls->input_line = shell_input_line;
1039+  ls->input_line_size = shell_input_line_size;
1040+  ls->input_line_len = shell_input_line_len;
1041+  ls->input_line_index = shell_input_line_index;
1042+
1043+  /* force reallocation */
1044+  shell_input_line = 0;
1045+  shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
1046+}
1047+
1048+void
1049+restore_input_line_state (ls)
1050+     sh_input_line_state_t *ls;
1051+{
1052+  FREE (shell_input_line);
1053+  shell_input_line = ls->input_line;
1054+  shell_input_line_size = ls->input_line_size;
1055+  shell_input_line_len = ls->input_line_len;
1056+  shell_input_line_index = ls->input_line_index;
1057+
1058+  set_line_mbstate ();
1059 }
1060 
1061 /************************************************
1062diff -Naur bash-4.2.orig/patchlevel.h bash-4.2/patchlevel.h
1063--- bash-4.2.orig/patchlevel.h  2010-06-13 00:14:48.000000000 +0000
1064+++ bash-4.2/patchlevel.h       2012-06-03 18:59:34.475691285 +0000
1065@@ -25,6 +25,6 @@
1066    regexp `^#define[   ]*PATCHLEVEL', since that's what support/mkversion.sh
1067    looks for to find the patch level (for the sccs version string). */
1068 
1069-#define PATCHLEVEL 0
1070+#define PATCHLEVEL 29
1071 
1072 #endif /* _PATCHLEVEL_H_ */
1073diff -Naur bash-4.2.orig/pathexp.c bash-4.2/pathexp.c
1074--- bash-4.2.orig/pathexp.c     2010-08-14 03:21:57.000000000 +0000
1075+++ bash-4.2/pathexp.c  2012-06-03 18:59:15.283171597 +0000
1076@@ -196,7 +196,7 @@
1077        {
1078          if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
1079            continue;
1080-         if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
1081+         if (pathname[i+1] != CTLESC && (qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
1082            continue;
1083          temp[j++] = '\\';
1084          i++;
1085diff -Naur bash-4.2.orig/print_cmd.c bash-4.2/print_cmd.c
1086--- bash-4.2.orig/print_cmd.c   2010-05-30 22:34:08.000000000 +0000
1087+++ bash-4.2/print_cmd.c        2012-06-03 18:59:10.179033384 +0000
1088@@ -315,6 +315,7 @@
1089          cprintf ("( ");
1090          skip_this_indent++;
1091          make_command_string_internal (command->value.Subshell->command);
1092+         PRINT_DEFERRED_HEREDOCS ("");
1093          cprintf (" )");
1094          break;
1095 
1096@@ -592,6 +593,7 @@
1097   newline ("do\n");
1098   indentation += indentation_amount;
1099   make_command_string_internal (arith_for_command->action);
1100+  PRINT_DEFERRED_HEREDOCS ("");
1101   semicolon ();
1102   indentation -= indentation_amount;
1103   newline ("done");
1104@@ -653,6 +655,7 @@
1105     }
1106 
1107   make_command_string_internal (group_command->command);
1108+  PRINT_DEFERRED_HEREDOCS ("");
1109 
1110   if (inside_function_def)
1111     {
1112diff -Naur bash-4.2.orig/shell.h bash-4.2/shell.h
1113--- bash-4.2.orig/shell.h       2011-01-07 03:16:55.000000000 +0000
1114+++ bash-4.2/shell.h    2012-06-03 18:59:12.711101949 +0000
1115@@ -136,6 +136,9 @@
1116   int parser_state;
1117   int *token_state;
1118 
1119+  char *token;
1120+  int token_buffer_size;
1121+
1122   /* input line state -- line number saved elsewhere */
1123   int input_line_terminator;
1124   int eof_encountered;
1125@@ -166,6 +169,16 @@
1126   
1127 } sh_parser_state_t;
1128 
1129+typedef struct _sh_input_line_state_t {
1130+  char *input_line;
1131+  int input_line_index;
1132+  int input_line_size;
1133+  int input_line_len;
1134+} sh_input_line_state_t;
1135+
1136 /* Let's try declaring these here. */
1137 extern sh_parser_state_t *save_parser_state __P((sh_parser_state_t *));
1138 extern void restore_parser_state __P((sh_parser_state_t *));
1139+
1140+extern sh_input_line_state_t *save_input_line_state __P((sh_input_line_state_t *));
1141+extern void restore_input_line_state __P((sh_input_line_state_t *));
1142diff -Naur bash-4.2.orig/sig.c bash-4.2/sig.c
1143--- bash-4.2.orig/sig.c 2010-11-23 13:21:22.000000000 +0000
1144+++ bash-4.2/sig.c      2012-06-03 18:59:07.650964928 +0000
1145@@ -46,6 +46,7 @@
1146 
1147 #if defined (READLINE)
1148 #  include "bashline.h"
1149+#  include <readline/readline.h>
1150 #endif
1151 
1152 #if defined (HISTORY)
1153@@ -62,6 +63,7 @@
1154 #if defined (HISTORY)
1155 extern int history_lines_this_session;
1156 #endif
1157+extern int no_line_editing;
1158 
1159 extern void initialize_siglist ();
1160 
1161@@ -505,7 +507,10 @@
1162     {
1163 #if defined (HISTORY)
1164       /* XXX - will inhibit history file being written */
1165-      history_lines_this_session = 0;
1166+#  if defined (READLINE)
1167+      if (interactive_shell == 0 || interactive == 0 || (sig != SIGHUP && sig != SIGTERM) || no_line_editing || (RL_ISSTATE (RL_STATE_READCMD) == 0))
1168+#  endif
1169+        history_lines_this_session = 0;
1170 #endif
1171       terminate_immediately = 0;
1172       termsig_handler (sig);
1173diff -Naur bash-4.2.orig/subst.c bash-4.2/subst.c
1174--- bash-4.2.orig/subst.c       2011-01-02 21:12:51.000000000 +0000
1175+++ bash-4.2/subst.c    2012-06-03 18:59:33.039652403 +0000
1176@@ -366,6 +366,11 @@
1177       f &= ~W_ASSNBLTIN;
1178       fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
1179     }
1180+  if (f & W_ASSNGLOBAL)
1181+    {
1182+      f &= ~W_ASSNGLOBAL;
1183+      fprintf (stderr, "W_ASSNGLOBAL%s", f ? "|" : "");
1184+    }
1185   if (f & W_COMPASSIGN)
1186     {
1187       f &= ~W_COMPASSIGN;
1188@@ -1379,10 +1384,12 @@
1189   slen = strlen (string + *sindex) + *sindex;
1190 
1191   /* The handling of dolbrace_state needs to agree with the code in parse.y:
1192-     parse_matched_pair() */
1193-  dolbrace_state = 0;
1194-  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1195-    dolbrace_state = (flags & SX_POSIXEXP) ? DOLBRACE_QUOTE : DOLBRACE_PARAM;
1196+     parse_matched_pair().  The different initial value is to handle the
1197+     case where this function is called to parse the word in
1198+     ${param op word} (SX_WORD). */
1199+  dolbrace_state = (flags & SX_WORD) ? DOLBRACE_WORD : DOLBRACE_PARAM;
1200+  if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && (flags & SX_POSIXEXP))
1201+    dolbrace_state = DOLBRACE_QUOTE;
1202 
1203   i = *sindex;
1204   while (c = string[i])
1205@@ -2801,7 +2808,7 @@
1206     }
1207   else if (assign_list)
1208     {
1209-      if (word->flags & W_ASSIGNARG)
1210+      if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL) == 0)
1211        aflags |= ASS_MKLOCAL;
1212       if (word->flags & W_ASSIGNASSOC)
1213        aflags |= ASS_MKASSOC;
1214@@ -3371,7 +3378,7 @@
1215   if (string == 0 || *string == '\0')
1216     return (WORD_LIST *)NULL;
1217 
1218-  td.flags = 0;
1219+  td.flags = W_NOSPLIT2;               /* no splitting, remove "" and '' */
1220   td.word = string;
1221   tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
1222   return (tresult);
1223@@ -3704,7 +3711,10 @@
1224            break;
1225        }
1226       else if (string[i] == CTLNUL)
1227-       i++;
1228+       {
1229+         i++;
1230+         continue;
1231+       }
1232 
1233       prev_i = i;
1234       ADVANCE_CHAR (string, slen, i);
1235@@ -4156,7 +4166,7 @@
1236   simple = (wpat[0] != L'\\' && wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'[');
1237 #if defined (EXTENDED_GLOB)
1238   if (extended_glob)
1239-    simple |= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
1240+    simple &= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
1241 #endif
1242 
1243   /* If the pattern doesn't match anywhere in the string, go ahead and
1244@@ -4607,6 +4617,7 @@
1245   if (ifs_firstc == 0)
1246 #endif
1247     word->flags |= W_NOSPLIT;
1248+  word->flags |= W_NOSPLIT2;
1249   result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
1250   expand_no_split_dollar_star = 0;
1251 
1252@@ -5798,6 +5809,16 @@
1253         is the only expansion that creates more than one word. */
1254       if (qdollaratp && ((hasdol && quoted) || l->next))
1255        *qdollaratp = 1;
1256+      /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
1257+        a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the
1258+        flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the
1259+        expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1260+        (which is more paranoia than anything else), we need to return the
1261+        quoted null string and set the flags to indicate it. */
1262+      if (l->next == 0 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL(temp) && QUOTED_NULL(l->word->word) && (l->word->flags & W_HASQUOTEDNULL))
1263+       {
1264+         w->flags |= W_HASQUOTEDNULL;
1265+       }
1266       dispose_words (l);
1267     }
1268   else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
1269@@ -7176,7 +7197,7 @@
1270     {
1271       /* Extract the contents of the ${ ... } expansion
1272         according to the Posix.2 rules. */
1273-      value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#') ? SX_POSIXEXP : 0);
1274+      value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#' || c =='/' || c == '^' || c == ',' || c ==':') ? SX_POSIXEXP|SX_WORD : SX_WORD);
1275       if (string[sindex] == RBRACE)
1276        sindex++;
1277       else
1278@@ -7268,6 +7289,7 @@
1279     default:
1280     case '\0':
1281     bad_substitution:
1282+      last_command_exit_value = EXECUTION_FAILURE;
1283       report_error (_("%s: bad substitution"), string ? string : "??");
1284       FREE (value);
1285       FREE (temp);
1286diff -Naur bash-4.2.orig/subst.h bash-4.2/subst.h
1287--- bash-4.2.orig/subst.h       2010-12-03 01:21:29.000000000 +0000
1288+++ bash-4.2/subst.h    2012-06-03 18:58:58.658721427 +0000
1289@@ -56,6 +56,7 @@
1290 #define SX_NOLONGJMP   0x0040  /* don't longjmp on fatal error */
1291 #define SX_ARITHSUB    0x0080  /* extracting $(( ... )) (currently unused) */
1292 #define SX_POSIXEXP    0x0100  /* extracting new Posix pattern removal expansions in extract_dollar_brace_string */
1293+#define SX_WORD                0x0200  /* extracting word in ${param op word} */
1294 
1295 /* Remove backslashes which are quoting backquotes from STRING.  Modifies
1296    STRING, and returns a pointer to it. */
1297diff -Naur bash-4.2.orig/support/shobj-conf bash-4.2/support/shobj-conf
1298--- bash-4.2.orig/support/shobj-conf    2009-10-28 13:20:21.000000000 +0000
1299+++ bash-4.2/support/shobj-conf 2012-06-03 18:59:22.927378587 +0000
1300@@ -157,7 +157,7 @@
1301        ;;
1302 
1303 # Darwin/MacOS X
1304-darwin[89]*|darwin10*)
1305+darwin[89]*|darwin1[012]*)
1306        SHOBJ_STATUS=supported
1307        SHLIB_STATUS=supported
1308       
1309@@ -186,7 +186,7 @@
1310        SHLIB_LIBSUFF='dylib'
1311 
1312        case "${host_os}" in
1313-       darwin[789]*|darwin10*) SHOBJ_LDFLAGS=''
1314+       darwin[789]*|darwin1[012]*)     SHOBJ_LDFLAGS=''
1315                        SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
1316                        ;;
1317        *)              SHOBJ_LDFLAGS='-dynamic'
1318diff -Naur bash-4.2.orig/tests/shopt.right bash-4.2/tests/shopt.right
1319--- bash-4.2.orig/tests/shopt.right     2010-07-03 03:36:30.000000000 +0000
1320+++ bash-4.2/tests/shopt.right  2012-06-03 18:59:34.475691285 +0000
1321@@ -12,6 +12,7 @@
1322 shopt -u compat32
1323 shopt -u compat40
1324 shopt -u compat41
1325+shopt -u direxpand
1326 shopt -u dirspell
1327 shopt -u dotglob
1328 shopt -u execfail
1329@@ -68,6 +69,7 @@
1330 shopt -u compat32
1331 shopt -u compat40
1332 shopt -u compat41
1333+shopt -u direxpand
1334 shopt -u dirspell
1335 shopt -u dotglob
1336 shopt -u execfail
1337@@ -101,6 +103,7 @@
1338 compat32               off
1339 compat40               off
1340 compat41               off
1341+direxpand              off
1342 dirspell               off
1343 dotglob                off
1344 execfail               off
1345diff -Naur bash-4.2.orig/variables.c bash-4.2/variables.c
1346--- bash-4.2.orig/variables.c   2011-01-25 01:07:48.000000000 +0000
1347+++ bash-4.2/variables.c        2012-06-03 18:59:05.082895387 +0000
1348@@ -3653,6 +3653,22 @@
1349   return n;
1350 }
1351 
1352+int
1353+chkexport (name)
1354+     char *name;
1355+{
1356+  SHELL_VAR *v;
1357+
1358+  v = find_variable (name);
1359+  if (v && exported_p (v))
1360+    {
1361+      array_needs_making = 1;
1362+      maybe_make_export_env ();
1363+      return 1;
1364+    }
1365+  return 0;
1366+}
1367+
1368 void
1369 maybe_make_export_env ()
1370 {
1371@@ -4214,7 +4230,7 @@
1372   { "TEXTDOMAIN", sv_locale },
1373   { "TEXTDOMAINDIR", sv_locale },
1374 
1375-#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
1376+#if defined (HAVE_TZSET)
1377   { "TZ", sv_tz },
1378 #endif
1379 
1380@@ -4558,12 +4574,13 @@
1381 }
1382 #endif /* HISTORY */
1383 
1384-#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
1385+#if defined (HAVE_TZSET)
1386 void
1387 sv_tz (name)
1388      char *name;
1389 {
1390-  tzset ();
1391+  if (chkexport (name))
1392+    tzset ();
1393 }
1394 #endif
1395 
1396diff -Naur bash-4.2.orig/variables.h bash-4.2/variables.h
1397--- bash-4.2.orig/variables.h   2010-12-03 01:22:01.000000000 +0000
1398+++ bash-4.2/variables.h        2012-06-03 18:59:03.798860619 +0000
1399@@ -313,6 +313,7 @@
1400 
1401 extern void sort_variables __P((SHELL_VAR **));
1402 
1403+extern int chkexport __P((char *));
1404 extern void maybe_make_export_env __P((void));
1405 extern void update_export_env_inplace __P((char *, int, char *));
1406 extern void put_command_name_into_env __P((char *));
Note: See TracBrowser for help on using the repository browser.