source: patches/bash-4.2-branch_update-6.patch@ 2bd7b2c

clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since 2bd7b2c was 31f34c6, checked in by William Harrington <kb0iic@…>, 12 years ago

Create bash branch update for level 39.

  • Property mode set to 100644
File size: 53.4 KB
RevLine 
[31f34c6]1Submitted By: William Harrington (kb0iic at gmail dot com)
2Date: 11-04-2012
3Initial Package Version: 4.2
4Origin: Upstream
5Upstream Status: Applied
6Description: Contains all upstream patches up to 4.2-039
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-11-04 22:45:00.778727333 +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-11-04 22:45:00.848727141 +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-11-04 22:45:00.848727141 +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-11-04 22:45:00.808727251 +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-11-04 22:45:00.775394009 +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/mapfile.def bash-4.2/builtins/mapfile.def
382--- bash-4.2.orig/builtins/mapfile.def 2010-05-30 02:09:47.000000000 +0000
383+++ bash-4.2/builtins/mapfile.def 2012-11-04 22:45:01.008726689 +0000
384@@ -195,13 +195,9 @@
385 /* Reset the buffer for bash own stream */
386 interrupt_immediately++;
387 for (array_index = origin, line_count = 1;
388- zgetline (fd, &line, &line_length, unbuffered_read) != -1;
389- array_index++, line_count++)
390+ zgetline (fd, &line, &line_length, unbuffered_read) != -1;
391+ array_index++)
392 {
393- /* Have we exceeded # of lines to store? */
394- if (line_count_goal != 0 && line_count > line_count_goal)
395- break;
396-
397 /* Remove trailing newlines? */
398 if (flags & MAPF_CHOP)
399 do_chop (line);
400@@ -217,6 +213,11 @@
401 }
402
403 bind_array_element (entry, array_index, line, 0);
404+
405+ /* Have we exceeded # of lines to store? */
406+ line_count++;
407+ if (line_count_goal != 0 && line_count > line_count_goal)
408+ break;
409 }
410
411 xfree (line);
412diff -Naur bash-4.2.orig/builtins/printf.def bash-4.2/builtins/printf.def
413--- bash-4.2.orig/builtins/printf.def 2010-11-23 15:02:55.000000000 +0000
414+++ bash-4.2/builtins/printf.def 2012-11-04 22:45:00.822060547 +0000
415@@ -255,6 +255,8 @@
416 #endif
417 {
418 vflag = 1;
419+ if (vbsize == 0)
420+ vbuf = xmalloc (vbsize = 16);
421 vblen = 0;
422 if (vbuf)
423 vbuf[0] = 0;
424@@ -465,6 +467,9 @@
425 secs = shell_start_time; /* roughly $SECONDS */
426 else
427 secs = arg;
428+#if defined (HAVE_TZSET)
429+ sv_tz ("TZ"); /* XXX -- just make sure */
430+#endif
431 tm = localtime (&secs);
432 n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
433 free (timefmt);
434diff -Naur bash-4.2.orig/builtins/read.def bash-4.2/builtins/read.def
435--- bash-4.2.orig/builtins/read.def 2011-01-04 16:43:36.000000000 +0000
436+++ bash-4.2/builtins/read.def 2012-11-04 22:45:01.032059959 +0000
437@@ -642,6 +642,12 @@
438 xfree (input_string);
439 return EXECUTION_FAILURE; /* readonly or noassign */
440 }
441+ if (assoc_p (var))
442+ {
443+ builtin_error (_("%s: cannot convert associative to indexed array"), arrayname);
444+ xfree (input_string);
445+ return EXECUTION_FAILURE; /* existing associative array */
446+ }
447 array_flush (array_cell (var));
448
449 alist = list_string (input_string, ifs_chars, 0);
450@@ -731,7 +737,7 @@
451 xfree (t1);
452 }
453 else
454- var = bind_read_variable (varname, t);
455+ var = bind_read_variable (varname, t ? t : "");
456 }
457 else
458 {
459@@ -785,14 +791,14 @@
460 }
461 #endif
462
463- if (saw_escape)
464+ if (saw_escape && input_string && *input_string)
465 {
466 t = dequote_string (input_string);
467 var = bind_read_variable (list->word->word, t);
468 xfree (t);
469 }
470 else
471- var = bind_read_variable (list->word->word, input_string);
472+ var = bind_read_variable (list->word->word, input_string ? input_string : "");
473
474 if (var)
475 {
476diff -Naur bash-4.2.orig/builtins/shopt.def bash-4.2/builtins/shopt.def
477--- bash-4.2.orig/builtins/shopt.def 2010-07-03 02:42:44.000000000 +0000
478+++ bash-4.2/builtins/shopt.def 2012-11-04 22:45:00.848727141 +0000
479@@ -61,6 +61,10 @@
480 #include "common.h"
481 #include "bashgetopt.h"
482
483+#if defined (READLINE)
484+# include "../bashline.h"
485+#endif
486+
487 #if defined (HISTORY)
488 # include "../bashhist.h"
489 #endif
490@@ -94,7 +98,7 @@
491 extern int hist_verify, history_reediting, perform_hostname_completion;
492 extern int no_empty_command_completion;
493 extern int force_fignore;
494-extern int dircomplete_spelling;
495+extern int dircomplete_spelling, dircomplete_expand;
496
497 extern int enable_hostname_completion __P((int));
498 #endif
499@@ -121,6 +125,10 @@
500 static int set_restricted_shell __P((char *, int));
501 #endif
502
503+#if defined (READLINE)
504+static int shopt_set_complete_direxpand __P((char *, int));
505+#endif
506+
507 static int shopt_login_shell;
508 static int shopt_compat31;
509 static int shopt_compat32;
510@@ -150,6 +158,7 @@
511 { "compat40", &shopt_compat40, set_compatibility_level },
512 { "compat41", &shopt_compat41, set_compatibility_level },
513 #if defined (READLINE)
514+ { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
515 { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
516 #endif
517 { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
518@@ -535,6 +544,17 @@
519 return 0;
520 }
521
522+#if defined (READLINE)
523+static int
524+shopt_set_complete_direxpand (option_name, mode)
525+ char *option_name;
526+ int mode;
527+{
528+ set_directory_hook ();
529+ return 0;
530+}
531+#endif
532+
533 #if defined (RESTRICTED_SHELL)
534 /* Don't allow the value of restricted_shell to be modified. */
535
536diff -Naur bash-4.2.orig/command.h bash-4.2/command.h
537--- bash-4.2.orig/command.h 2010-08-02 23:36:51.000000000 +0000
538+++ bash-4.2/command.h 2012-11-04 22:45:00.825393871 +0000
539@@ -97,6 +97,7 @@
540 #define W_HASCTLESC 0x200000 /* word contains literal CTLESC characters */
541 #define W_ASSIGNASSOC 0x400000 /* word looks like associative array assignment */
542 #define W_ARRAYIND 0x800000 /* word is an array index being expanded */
543+#define W_ASSNGLOBAL 0x1000000 /* word is a global assignment to declare (declare/typeset -g) */
544
545 /* Possible values for subshell_environment */
546 #define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */
547diff -Naur bash-4.2.orig/doc/bash.1 bash-4.2/doc/bash.1
548--- bash-4.2.orig/doc/bash.1 2011-01-16 20:31:39.000000000 +0000
549+++ bash-4.2/doc/bash.1 2012-11-04 22:45:00.855393789 +0000
550@@ -8948,6 +8948,16 @@
551 quoted. This is the behavior of posix mode through version 4.1.
552 The default bash behavior remains as in previous versions.
553 .TP 8
554+.B direxpand
555+If set,
556+.B bash
557+replaces directory names with the results of word expansion when performing
558+filename completion. This changes the contents of the readline editing
559+buffer.
560+If not set,
561+.B bash
562+attempts to preserve what the user typed.
563+.TP 8
564 .B dirspell
565 If set,
566 .B bash
567diff -Naur bash-4.2.orig/doc/bashref.texi bash-4.2/doc/bashref.texi
568--- bash-4.2.orig/doc/bashref.texi 2011-01-16 20:31:57.000000000 +0000
569+++ bash-4.2/doc/bashref.texi 2012-11-04 22:45:00.858727113 +0000
570@@ -4535,6 +4535,13 @@
571 quoted. This is the behavior of @sc{posix} mode through version 4.1.
572 The default Bash behavior remains as in previous versions.
573
574+@item direxpand
575+If set, Bash
576+replaces directory names with the results of word expansion when performing
577+filename completion. This changes the contents of the readline editing
578+buffer.
579+If not set, Bash attempts to preserve what the user typed.
580+
581 @item dirspell
582 If set, Bash
583 attempts spelling correction on directory names during word completion
584diff -Naur bash-4.2.orig/error.c bash-4.2/error.c
585--- bash-4.2.orig/error.c 2009-08-22 02:31:31.000000000 +0000
586+++ bash-4.2/error.c 2012-11-04 22:45:00.822060547 +0000
587@@ -200,7 +200,11 @@
588
589 va_end (args);
590 if (exit_immediately_on_error)
591- exit_shell (1);
592+ {
593+ if (last_command_exit_value == 0)
594+ last_command_exit_value = 1;
595+ exit_shell (last_command_exit_value);
596+ }
597 }
598
599 void
600diff -Naur bash-4.2.orig/execute_cmd.c bash-4.2/execute_cmd.c
601--- bash-4.2.orig/execute_cmd.c 2011-02-09 22:32:25.000000000 +0000
602+++ bash-4.2/execute_cmd.c 2012-11-04 22:45:00.835393844 +0000
603@@ -2196,6 +2196,7 @@
604 if (ignore_return && cmd)
605 cmd->flags |= CMD_IGNORE_RETURN;
606
607+#if defined (JOB_CONTROL)
608 lastpipe_flag = 0;
609 begin_unwind_frame ("lastpipe-exec");
610 lstdin = -1;
611@@ -2204,7 +2205,7 @@
612 current shell environment. */
613 if (lastpipe_opt && job_control == 0 && asynchronous == 0 && pipe_out == NO_PIPE && prev > 0)
614 {
615- lstdin = move_to_high_fd (0, 0, 255);
616+ lstdin = move_to_high_fd (0, 1, -1);
617 if (lstdin > 0)
618 {
619 do_piping (prev, pipe_out);
620@@ -2215,15 +2216,19 @@
621 lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL); /* XXX */
622 add_unwind_protect (lastpipe_cleanup, lastpipe_jid);
623 }
624- cmd->flags |= CMD_LASTPIPE;
625+ if (cmd)
626+ cmd->flags |= CMD_LASTPIPE;
627 }
628 if (prev >= 0)
629 add_unwind_protect (close, prev);
630+#endif
631
632 exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close);
633
634+#if defined (JOB_CONTROL)
635 if (lstdin > 0)
636 restore_stdin (lstdin);
637+#endif
638
639 if (prev >= 0)
640 close (prev);
641@@ -2246,7 +2251,9 @@
642 unfreeze_jobs_list ();
643 }
644
645+#if defined (JOB_CONTROL)
646 discard_unwind_frame ("lastpipe-exec");
647+#endif
648
649 return (exec_result);
650 }
651@@ -3575,13 +3582,13 @@
652 {
653 WORD_LIST *w;
654 struct builtin *b;
655- int assoc;
656+ int assoc, global;
657
658 if (words == 0)
659 return;
660
661 b = 0;
662- assoc = 0;
663+ assoc = global = 0;
664
665 for (w = words; w; w = w->next)
666 if (w->word->flags & W_ASSIGNMENT)
667@@ -3598,12 +3605,17 @@
668 #if defined (ARRAY_VARS)
669 if (assoc)
670 w->word->flags |= W_ASSIGNASSOC;
671+ if (global)
672+ w->word->flags |= W_ASSNGLOBAL;
673 #endif
674 }
675 #if defined (ARRAY_VARS)
676 /* Note that we saw an associative array option to a builtin that takes
677 assignment statements. This is a bit of a kludge. */
678- else if (w->word->word[0] == '-' && strchr (w->word->word, 'A'))
679+ else if (w->word->word[0] == '-' && (strchr (w->word->word+1, 'A') || strchr (w->word->word+1, 'g')))
680+#else
681+ else if (w->word->word[0] == '-' && strchr (w->word->word+1, 'g'))
682+#endif
683 {
684 if (b == 0)
685 {
686@@ -3613,10 +3625,11 @@
687 else if (b && (b->flags & ASSIGNMENT_BUILTIN))
688 words->word->flags |= W_ASSNBLTIN;
689 }
690- if (words->word->flags & W_ASSNBLTIN)
691+ if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'A'))
692 assoc = 1;
693+ if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'g'))
694+ global = 1;
695 }
696-#endif
697 }
698
699 /* Return 1 if the file found by searching $PATH for PATHNAME, defaulting
700diff -Naur bash-4.2.orig/expr.c bash-4.2/expr.c
701--- bash-4.2.orig/expr.c 2010-12-21 16:12:13.000000000 +0000
702+++ bash-4.2/expr.c 2012-11-04 22:45:01.038726607 +0000
703@@ -476,19 +476,23 @@
704
705 if (special)
706 {
707+ if ((op == DIV || op == MOD) && value == 0)
708+ {
709+ if (noeval == 0)
710+ evalerror (_("division by 0"));
711+ else
712+ value = 1;
713+ }
714+
715 switch (op)
716 {
717 case MUL:
718 lvalue *= value;
719 break;
720 case DIV:
721- if (value == 0)
722- evalerror (_("division by 0"));
723 lvalue /= value;
724 break;
725 case MOD:
726- if (value == 0)
727- evalerror (_("division by 0"));
728 lvalue %= value;
729 break;
730 case PLUS:
731@@ -804,7 +808,12 @@
732 val2 = exppower ();
733
734 if (((op == DIV) || (op == MOD)) && (val2 == 0))
735- evalerror (_("division by 0"));
736+ {
737+ if (noeval == 0)
738+ evalerror (_("division by 0"));
739+ else
740+ val2 = 1;
741+ }
742
743 if (op == MUL)
744 val1 *= val2;
745@@ -1000,6 +1009,12 @@
746 arrayind_t ind;
747 #endif
748
749+/*itrace("expr_streval: %s: noeval = %d", tok, noeval);*/
750+ /* If we are suppressing evaluation, just short-circuit here instead of
751+ going through the rest of the evaluator. */
752+ if (noeval)
753+ return (0);
754+
755 /* [[[[[ */
756 #if defined (ARRAY_VARS)
757 v = (e == ']') ? array_variable_part (tok, (char **)0, (int *)0) : find_variable (tok);
758@@ -1173,6 +1188,10 @@
759 #endif /* ARRAY_VARS */
760
761 *cp = '\0';
762+ /* XXX - watch out for pointer aliasing issues here */
763+ if (curlval.tokstr && curlval.tokstr == tokstr)
764+ init_lvalue (&curlval);
765+
766 FREE (tokstr);
767 tokstr = savestring (tp);
768 *cp = c;
769diff -Naur bash-4.2.orig/lib/glob/glob.c bash-4.2/lib/glob/glob.c
770--- bash-4.2.orig/lib/glob/glob.c 2009-11-14 23:39:30.000000000 +0000
771+++ bash-4.2/lib/glob/glob.c 2012-11-04 22:45:00.862060437 +0000
772@@ -200,8 +200,11 @@
773 wchar_t *pat_wc, *dn_wc;
774 size_t pat_n, dn_n;
775
776+ pat_wc = dn_wc = (wchar_t *)NULL;
777+
778 pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
779- dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
780+ if (pat_n != (size_t)-1)
781+ dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
782
783 ret = 0;
784 if (pat_n != (size_t)-1 && dn_n !=(size_t)-1)
785@@ -221,6 +224,8 @@
786 (pat_wc[0] != L'\\' || pat_wc[1] != L'.'))
787 ret = 1;
788 }
789+ else
790+ ret = skipname (pat, dname, flags);
791
792 FREE (pat_wc);
793 FREE (dn_wc);
794@@ -266,8 +271,11 @@
795 /* Convert the strings into wide characters. */
796 n = xdupmbstowcs (&wpathname, NULL, pathname);
797 if (n == (size_t) -1)
798- /* Something wrong. */
799- return;
800+ {
801+ /* Something wrong. Fall back to single-byte */
802+ udequote_pathname (pathname);
803+ return;
804+ }
805 orig_wpathname = wpathname;
806
807 for (i = j = 0; wpathname && wpathname[i]; )
808diff -Naur bash-4.2.orig/lib/glob/gmisc.c bash-4.2/lib/glob/gmisc.c
809--- bash-4.2.orig/lib/glob/gmisc.c 2011-02-05 21:11:17.000000000 +0000
810+++ bash-4.2/lib/glob/gmisc.c 2012-11-04 22:45:00.748727415 +0000
811@@ -77,8 +77,8 @@
812 wchar_t *wpat;
813 size_t wmax;
814 {
815- wchar_t wc, *wbrack;
816- int matlen, t, in_cclass, in_collsym, in_equiv;
817+ wchar_t wc;
818+ int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
819
820 if (*wpat == 0)
821 return (0);
822@@ -118,58 +118,80 @@
823 break;
824 case L'[':
825 /* scan for ending `]', skipping over embedded [:...:] */
826- wbrack = wpat;
827+ bracklen = 1;
828 wc = *wpat++;
829 do
830 {
831 if (wc == 0)
832 {
833- matlen += wpat - wbrack - 1; /* incremented below */
834- break;
835+ wpat--; /* back up to NUL */
836+ matlen += bracklen;
837+ goto bad_bracket;
838 }
839 else if (wc == L'\\')
840 {
841- wc = *wpat++;
842- if (*wpat == 0)
843- break;
844+ /* *wpat == backslash-escaped character */
845+ bracklen++;
846+ /* If the backslash or backslash-escape ends the string,
847+ bail. The ++wpat skips over the backslash escape */
848+ if (*wpat == 0 || *++wpat == 0)
849+ {
850+ matlen += bracklen;
851+ goto bad_bracket;
852+ }
853 }
854 else if (wc == L'[' && *wpat == L':') /* character class */
855 {
856 wpat++;
857+ bracklen++;
858 in_cclass = 1;
859 }
860 else if (in_cclass && wc == L':' && *wpat == L']')
861 {
862 wpat++;
863+ bracklen++;
864 in_cclass = 0;
865 }
866 else if (wc == L'[' && *wpat == L'.') /* collating symbol */
867 {
868 wpat++;
869+ bracklen++;
870 if (*wpat == L']') /* right bracket can appear as collating symbol */
871- wpat++;
872+ {
873+ wpat++;
874+ bracklen++;
875+ }
876 in_collsym = 1;
877 }
878 else if (in_collsym && wc == L'.' && *wpat == L']')
879 {
880 wpat++;
881+ bracklen++;
882 in_collsym = 0;
883 }
884 else if (wc == L'[' && *wpat == L'=') /* equivalence class */
885 {
886 wpat++;
887+ bracklen++;
888 if (*wpat == L']') /* right bracket can appear as equivalence class */
889- wpat++;
890+ {
891+ wpat++;
892+ bracklen++;
893+ }
894 in_equiv = 1;
895 }
896 else if (in_equiv && wc == L'=' && *wpat == L']')
897 {
898 wpat++;
899+ bracklen++;
900 in_equiv = 0;
901 }
902+ else
903+ bracklen++;
904 }
905 while ((wc = *wpat++) != L']');
906 matlen++; /* bracket expression can only match one char */
907+bad_bracket:
908 break;
909 }
910 }
911@@ -213,8 +235,8 @@
912 char *pat;
913 size_t max;
914 {
915- char c, *brack;
916- int matlen, t, in_cclass, in_collsym, in_equiv;
917+ char c;
918+ int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
919
920 if (*pat == 0)
921 return (0);
922@@ -254,58 +276,80 @@
923 break;
924 case '[':
925 /* scan for ending `]', skipping over embedded [:...:] */
926- brack = pat;
927+ bracklen = 1;
928 c = *pat++;
929 do
930 {
931 if (c == 0)
932 {
933- matlen += pat - brack - 1; /* incremented below */
934- break;
935+ pat--; /* back up to NUL */
936+ matlen += bracklen;
937+ goto bad_bracket;
938 }
939 else if (c == '\\')
940 {
941- c = *pat++;
942- if (*pat == 0)
943- break;
944+ /* *pat == backslash-escaped character */
945+ bracklen++;
946+ /* If the backslash or backslash-escape ends the string,
947+ bail. The ++pat skips over the backslash escape */
948+ if (*pat == 0 || *++pat == 0)
949+ {
950+ matlen += bracklen;
951+ goto bad_bracket;
952+ }
953 }
954 else if (c == '[' && *pat == ':') /* character class */
955 {
956 pat++;
957+ bracklen++;
958 in_cclass = 1;
959 }
960 else if (in_cclass && c == ':' && *pat == ']')
961 {
962 pat++;
963+ bracklen++;
964 in_cclass = 0;
965 }
966 else if (c == '[' && *pat == '.') /* collating symbol */
967 {
968 pat++;
969+ bracklen++;
970 if (*pat == ']') /* right bracket can appear as collating symbol */
971- pat++;
972+ {
973+ pat++;
974+ bracklen++;
975+ }
976 in_collsym = 1;
977 }
978 else if (in_collsym && c == '.' && *pat == ']')
979 {
980 pat++;
981+ bracklen++;
982 in_collsym = 0;
983 }
984 else if (c == '[' && *pat == '=') /* equivalence class */
985 {
986 pat++;
987+ bracklen++;
988 if (*pat == ']') /* right bracket can appear as equivalence class */
989- pat++;
990+ {
991+ pat++;
992+ bracklen++;
993+ }
994 in_equiv = 1;
995 }
996 else if (in_equiv && c == '=' && *pat == ']')
997 {
998 pat++;
999+ bracklen++;
1000 in_equiv = 0;
1001 }
1002+ else
1003+ bracklen++;
1004 }
1005 while ((c = *pat++) != ']');
1006 matlen++; /* bracket expression can only match one char */
1007+bad_bracket:
1008 break;
1009 }
1010 }
1011diff -Naur bash-4.2.orig/lib/glob/xmbsrtowcs.c bash-4.2/lib/glob/xmbsrtowcs.c
1012--- bash-4.2.orig/lib/glob/xmbsrtowcs.c 2010-05-30 22:36:27.000000000 +0000
1013+++ bash-4.2/lib/glob/xmbsrtowcs.c 2012-11-04 22:45:00.862060437 +0000
1014@@ -35,6 +35,8 @@
1015
1016 #if HANDLE_MULTIBYTE
1017
1018+#define WSBUF_INC 32
1019+
1020 #ifndef FREE
1021 # define FREE(x) do { if (x) free (x); } while (0)
1022 #endif
1023@@ -148,7 +150,7 @@
1024 size_t wsbuf_size; /* Size of WSBUF */
1025 size_t wcnum; /* Number of wide characters in WSBUF */
1026 mbstate_t state; /* Conversion State */
1027- size_t wcslength; /* Number of wide characters produced by the conversion. */
1028+ size_t n, wcslength; /* Number of wide characters produced by the conversion. */
1029 const char *end_or_backslash;
1030 size_t nms; /* Number of multibyte characters to convert at one time. */
1031 mbstate_t tmp_state;
1032@@ -171,7 +173,18 @@
1033 /* Compute the number of produced wide-characters. */
1034 tmp_p = p;
1035 tmp_state = state;
1036- wcslength = mbsnrtowcs(NULL, &tmp_p, nms, 0, &tmp_state);
1037+
1038+ if (nms == 0 && *p == '\\') /* special initial case */
1039+ nms = wcslength = 1;
1040+ else
1041+ wcslength = mbsnrtowcs (NULL, &tmp_p, nms, 0, &tmp_state);
1042+
1043+ if (wcslength == 0)
1044+ {
1045+ tmp_p = p; /* will need below */
1046+ tmp_state = state;
1047+ wcslength = 1; /* take a single byte */
1048+ }
1049
1050 /* Conversion failed. */
1051 if (wcslength == (size_t)-1)
1052@@ -186,7 +199,8 @@
1053 {
1054 wchar_t *wstmp;
1055
1056- wsbuf_size = wcnum+wcslength+1; /* 1 for the L'\0' or the potential L'\\' */
1057+ while (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */
1058+ wsbuf_size += WSBUF_INC;
1059
1060 wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
1061 if (wstmp == NULL)
1062@@ -199,10 +213,18 @@
1063 }
1064
1065 /* Perform the conversion. This is assumed to return 'wcslength'.
1066- * It may set 'p' to NULL. */
1067- mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);
1068+ It may set 'p' to NULL. */
1069+ n = mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);
1070
1071- wcnum += wcslength;
1072+ /* Compensate for taking single byte on wcs conversion failure above. */
1073+ if (wcslength == 1 && (n == 0 || n == (size_t)-1))
1074+ {
1075+ state = tmp_state;
1076+ p = tmp_p;
1077+ wsbuf[wcnum++] = *p++;
1078+ }
1079+ else
1080+ wcnum += wcslength;
1081
1082 if (mbsinit (&state) && (p != NULL) && (*p == '\\'))
1083 {
1084@@ -230,8 +252,6 @@
1085 If conversion is failed, the return value is (size_t)-1 and the values
1086 of DESTP and INDICESP are NULL. */
1087
1088-#define WSBUF_INC 32
1089-
1090 size_t
1091 xdupmbstowcs (destp, indicesp, src)
1092 wchar_t **destp; /* Store the pointer to the wide character string */
1093diff -Naur bash-4.2.orig/lib/readline/callback.c bash-4.2/lib/readline/callback.c
1094--- bash-4.2.orig/lib/readline/callback.c 2010-06-06 16:18:58.000000000 +0000
1095+++ bash-4.2/lib/readline/callback.c 2012-11-04 22:45:00.718727497 +0000
1096@@ -148,6 +148,9 @@
1097 eof = _rl_vi_domove_callback (_rl_vimvcxt);
1098 /* Should handle everything, including cleanup, numeric arguments,
1099 and turning off RL_STATE_VIMOTION */
1100+ if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
1101+ _rl_internal_char_cleanup ();
1102+
1103 return;
1104 }
1105 #endif
1106diff -Naur bash-4.2.orig/lib/readline/input.c bash-4.2/lib/readline/input.c
1107--- bash-4.2.orig/lib/readline/input.c 2010-05-30 22:33:01.000000000 +0000
1108+++ bash-4.2/lib/readline/input.c 2012-11-04 22:45:00.982060097 +0000
1109@@ -409,7 +409,7 @@
1110 int
1111 rl_read_key ()
1112 {
1113- int c;
1114+ int c, r;
1115
1116 rl_key_sequence_length++;
1117
1118@@ -429,14 +429,18 @@
1119 {
1120 while (rl_event_hook)
1121 {
1122- if (rl_gather_tyi () < 0) /* XXX - EIO */
1123+ if (rl_get_char (&c) != 0)
1124+ break;
1125+
1126+ if ((r = rl_gather_tyi ()) < 0) /* XXX - EIO */
1127 {
1128 rl_done = 1;
1129 return ('\n');
1130 }
1131+ else if (r == 1) /* read something */
1132+ continue;
1133+
1134 RL_CHECK_SIGNALS ();
1135- if (rl_get_char (&c) != 0)
1136- break;
1137 if (rl_done) /* XXX - experimental */
1138 return ('\n');
1139 (*rl_event_hook) ();
1140diff -Naur bash-4.2.orig/lib/readline/vi_mode.c bash-4.2/lib/readline/vi_mode.c
1141--- bash-4.2.orig/lib/readline/vi_mode.c 2010-11-21 00:51:39.000000000 +0000
1142+++ bash-4.2/lib/readline/vi_mode.c 2012-11-04 22:45:01.025393311 +0000
1143@@ -1114,7 +1114,7 @@
1144 rl_beg_of_line (1, c);
1145 _rl_vi_last_motion = c;
1146 RL_UNSETSTATE (RL_STATE_VIMOTION);
1147- return (0);
1148+ return (vidomove_dispatch (m));
1149 }
1150 #if defined (READLINE_CALLBACKS)
1151 /* XXX - these need to handle rl_universal_argument bindings */
1152@@ -1234,11 +1234,19 @@
1153 _rl_vimvcxt->motion = '$';
1154 r = rl_domove_motion_callback (_rl_vimvcxt);
1155 }
1156- else if (vi_redoing)
1157+ else if (vi_redoing && _rl_vi_last_motion != 'd') /* `dd' is special */
1158 {
1159 _rl_vimvcxt->motion = _rl_vi_last_motion;
1160 r = rl_domove_motion_callback (_rl_vimvcxt);
1161 }
1162+ else if (vi_redoing) /* handle redoing `dd' here */
1163+ {
1164+ _rl_vimvcxt->motion = _rl_vi_last_motion;
1165+ rl_mark = rl_end;
1166+ rl_beg_of_line (1, key);
1167+ RL_UNSETSTATE (RL_STATE_VIMOTION);
1168+ r = vidomove_dispatch (_rl_vimvcxt);
1169+ }
1170 #if defined (READLINE_CALLBACKS)
1171 else if (RL_ISSTATE (RL_STATE_CALLBACK))
1172 {
1173@@ -1316,11 +1324,19 @@
1174 _rl_vimvcxt->motion = '$';
1175 r = rl_domove_motion_callback (_rl_vimvcxt);
1176 }
1177- else if (vi_redoing)
1178+ else if (vi_redoing && _rl_vi_last_motion != 'c') /* `cc' is special */
1179 {
1180 _rl_vimvcxt->motion = _rl_vi_last_motion;
1181 r = rl_domove_motion_callback (_rl_vimvcxt);
1182 }
1183+ else if (vi_redoing) /* handle redoing `cc' here */
1184+ {
1185+ _rl_vimvcxt->motion = _rl_vi_last_motion;
1186+ rl_mark = rl_end;
1187+ rl_beg_of_line (1, key);
1188+ RL_UNSETSTATE (RL_STATE_VIMOTION);
1189+ r = vidomove_dispatch (_rl_vimvcxt);
1190+ }
1191 #if defined (READLINE_CALLBACKS)
1192 else if (RL_ISSTATE (RL_STATE_CALLBACK))
1193 {
1194@@ -1377,6 +1393,19 @@
1195 _rl_vimvcxt->motion = '$';
1196 r = rl_domove_motion_callback (_rl_vimvcxt);
1197 }
1198+ else if (vi_redoing && _rl_vi_last_motion != 'y') /* `yy' is special */
1199+ {
1200+ _rl_vimvcxt->motion = _rl_vi_last_motion;
1201+ r = rl_domove_motion_callback (_rl_vimvcxt);
1202+ }
1203+ else if (vi_redoing) /* handle redoing `yy' here */
1204+ {
1205+ _rl_vimvcxt->motion = _rl_vi_last_motion;
1206+ rl_mark = rl_end;
1207+ rl_beg_of_line (1, key);
1208+ RL_UNSETSTATE (RL_STATE_VIMOTION);
1209+ r = vidomove_dispatch (_rl_vimvcxt);
1210+ }
1211 #if defined (READLINE_CALLBACKS)
1212 else if (RL_ISSTATE (RL_STATE_CALLBACK))
1213 {
1214diff -Naur bash-4.2.orig/lib/sh/eaccess.c bash-4.2/lib/sh/eaccess.c
1215--- bash-4.2.orig/lib/sh/eaccess.c 2011-01-09 01:50:10.000000000 +0000
1216+++ bash-4.2/lib/sh/eaccess.c 2012-11-04 22:45:00.995393393 +0000
1217@@ -82,6 +82,8 @@
1218 const char *path;
1219 struct stat *finfo;
1220 {
1221+ static char *pbuf = 0;
1222+
1223 if (*path == '\0')
1224 {
1225 errno = ENOENT;
1226@@ -106,7 +108,7 @@
1227 trailing slash. Make sure /dev/fd/xx really uses DEV_FD_PREFIX/xx.
1228 On most systems, with the notable exception of linux, this is
1229 effectively a no-op. */
1230- char pbuf[32];
1231+ pbuf = xrealloc (pbuf, sizeof (DEV_FD_PREFIX) + strlen (path + 8));
1232 strcpy (pbuf, DEV_FD_PREFIX);
1233 strcat (pbuf, path + 8);
1234 return (stat (pbuf, finfo));
1235diff -Naur bash-4.2.orig/lib/sh/zread.c bash-4.2/lib/sh/zread.c
1236--- bash-4.2.orig/lib/sh/zread.c 2009-03-02 13:54:45.000000000 +0000
1237+++ bash-4.2/lib/sh/zread.c 2012-11-04 22:45:00.815393899 +0000
1238@@ -160,14 +160,13 @@
1239 zsyncfd (fd)
1240 int fd;
1241 {
1242- off_t off;
1243- int r;
1244+ off_t off, r;
1245
1246 off = lused - lind;
1247 r = 0;
1248 if (off > 0)
1249 r = lseek (fd, -off, SEEK_CUR);
1250
1251- if (r >= 0)
1252+ if (r != -1)
1253 lused = lind = 0;
1254 }
1255diff -Naur bash-4.2.orig/parse.y bash-4.2/parse.y
1256--- bash-4.2.orig/parse.y 2011-01-02 20:48:11.000000000 +0000
1257+++ bash-4.2/parse.y 2012-11-04 22:45:01.005393365 +0000
1258@@ -2499,7 +2499,7 @@
1259 We do this only if it is time to do so. Notice that only here
1260 is the mail alarm reset; nothing takes place in check_mail ()
1261 except the checking of mail. Please don't change this. */
1262- if (prompt_is_ps1 && time_to_check_mail ())
1263+ if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ())
1264 {
1265 check_mail ();
1266 reset_mail_timer ();
1267@@ -3842,6 +3842,7 @@
1268 int flags;
1269 {
1270 sh_parser_state_t ps;
1271+ sh_input_line_state_t ls;
1272 int orig_ind, nc, sflags;
1273 char *ret, *s, *ep, *ostring;
1274
1275@@ -3849,10 +3850,12 @@
1276 orig_ind = *indp;
1277 ostring = string;
1278
1279+/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/
1280 sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
1281 if (flags & SX_NOLONGJMP)
1282 sflags |= SEVAL_NOLONGJMP;
1283 save_parser_state (&ps);
1284+ save_input_line_state (&ls);
1285
1286 /*(*/
1287 parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/
1288@@ -3861,6 +3864,8 @@
1289
1290 restore_parser_state (&ps);
1291 reset_parser ();
1292+ /* reset_parser clears shell_input_line and associated variables */
1293+ restore_input_line_state (&ls);
1294 if (interactive)
1295 token_to_read = 0;
1296
1297@@ -4895,6 +4900,9 @@
1298 return (current_command_line_count == 2 ? "\n" : "");
1299 }
1300
1301+ if (parser_state & PST_COMPASSIGN)
1302+ return (" ");
1303+
1304 /* First, handle some special cases. */
1305 /*(*/
1306 /* If we just read `()', assume it's a function definition, and don't
1307@@ -5135,6 +5143,9 @@
1308 case 'A':
1309 /* Make the current time/date into a string. */
1310 (void) time (&the_time);
1311+#if defined (HAVE_TZSET)
1312+ sv_tz ("TZ"); /* XXX -- just make sure */
1313+#endif
1314 tm = localtime (&the_time);
1315
1316 if (c == 'd')
1317@@ -5905,6 +5916,12 @@
1318 ps->expand_aliases = expand_aliases;
1319 ps->echo_input_at_read = echo_input_at_read;
1320
1321+ ps->token = token;
1322+ ps->token_buffer_size = token_buffer_size;
1323+ /* Force reallocation on next call to read_token_word */
1324+ token = 0;
1325+ token_buffer_size = 0;
1326+
1327 return (ps);
1328 }
1329
1330@@ -5946,6 +5963,42 @@
1331
1332 expand_aliases = ps->expand_aliases;
1333 echo_input_at_read = ps->echo_input_at_read;
1334+
1335+ FREE (token);
1336+ token = ps->token;
1337+ token_buffer_size = ps->token_buffer_size;
1338+}
1339+
1340+sh_input_line_state_t *
1341+save_input_line_state (ls)
1342+ sh_input_line_state_t *ls;
1343+{
1344+ if (ls == 0)
1345+ ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
1346+ if (ls == 0)
1347+ return ((sh_input_line_state_t *)NULL);
1348+
1349+ ls->input_line = shell_input_line;
1350+ ls->input_line_size = shell_input_line_size;
1351+ ls->input_line_len = shell_input_line_len;
1352+ ls->input_line_index = shell_input_line_index;
1353+
1354+ /* force reallocation */
1355+ shell_input_line = 0;
1356+ shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
1357+}
1358+
1359+void
1360+restore_input_line_state (ls)
1361+ sh_input_line_state_t *ls;
1362+{
1363+ FREE (shell_input_line);
1364+ shell_input_line = ls->input_line;
1365+ shell_input_line_size = ls->input_line_size;
1366+ shell_input_line_len = ls->input_line_len;
1367+ shell_input_line_index = ls->input_line_index;
1368+
1369+ set_line_mbstate ();
1370 }
1371
1372 /************************************************
1373diff -Naur bash-4.2.orig/patchlevel.h bash-4.2/patchlevel.h
1374--- bash-4.2.orig/patchlevel.h 2010-06-13 00:14:48.000000000 +0000
1375+++ bash-4.2/patchlevel.h 2012-11-04 22:45:01.038726607 +0000
1376@@ -25,6 +25,6 @@
1377 regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
1378 looks for to find the patch level (for the sccs version string). */
1379
1380-#define PATCHLEVEL 0
1381+#define PATCHLEVEL 39
1382
1383 #endif /* _PATCHLEVEL_H_ */
1384diff -Naur bash-4.2.orig/pathexp.c bash-4.2/pathexp.c
1385--- bash-4.2.orig/pathexp.c 2010-08-14 03:21:57.000000000 +0000
1386+++ bash-4.2/pathexp.c 2012-11-04 22:45:00.792060629 +0000
1387@@ -196,7 +196,7 @@
1388 {
1389 if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
1390 continue;
1391- if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
1392+ if (pathname[i+1] != CTLESC && (qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
1393 continue;
1394 temp[j++] = '\\';
1395 i++;
1396diff -Naur bash-4.2.orig/print_cmd.c bash-4.2/print_cmd.c
1397--- bash-4.2.orig/print_cmd.c 2010-05-30 22:34:08.000000000 +0000
1398+++ bash-4.2/print_cmd.c 2012-11-04 22:45:00.778727333 +0000
1399@@ -315,6 +315,7 @@
1400 cprintf ("( ");
1401 skip_this_indent++;
1402 make_command_string_internal (command->value.Subshell->command);
1403+ PRINT_DEFERRED_HEREDOCS ("");
1404 cprintf (" )");
1405 break;
1406
1407@@ -592,6 +593,7 @@
1408 newline ("do\n");
1409 indentation += indentation_amount;
1410 make_command_string_internal (arith_for_command->action);
1411+ PRINT_DEFERRED_HEREDOCS ("");
1412 semicolon ();
1413 indentation -= indentation_amount;
1414 newline ("done");
1415@@ -653,6 +655,7 @@
1416 }
1417
1418 make_command_string_internal (group_command->command);
1419+ PRINT_DEFERRED_HEREDOCS ("");
1420
1421 if (inside_function_def)
1422 {
1423diff -Naur bash-4.2.orig/shell.h bash-4.2/shell.h
1424--- bash-4.2.orig/shell.h 2011-01-07 03:16:55.000000000 +0000
1425+++ bash-4.2/shell.h 2012-11-04 22:45:00.785393981 +0000
1426@@ -136,6 +136,9 @@
1427 int parser_state;
1428 int *token_state;
1429
1430+ char *token;
1431+ int token_buffer_size;
1432+
1433 /* input line state -- line number saved elsewhere */
1434 int input_line_terminator;
1435 int eof_encountered;
1436@@ -166,6 +169,16 @@
1437
1438 } sh_parser_state_t;
1439
1440+typedef struct _sh_input_line_state_t {
1441+ char *input_line;
1442+ int input_line_index;
1443+ int input_line_size;
1444+ int input_line_len;
1445+} sh_input_line_state_t;
1446+
1447 /* Let's try declaring these here. */
1448 extern sh_parser_state_t *save_parser_state __P((sh_parser_state_t *));
1449 extern void restore_parser_state __P((sh_parser_state_t *));
1450+
1451+extern sh_input_line_state_t *save_input_line_state __P((sh_input_line_state_t *));
1452+extern void restore_input_line_state __P((sh_input_line_state_t *));
1453diff -Naur bash-4.2.orig/sig.c bash-4.2/sig.c
1454--- bash-4.2.orig/sig.c 2010-11-23 13:21:22.000000000 +0000
1455+++ bash-4.2/sig.c 2012-11-04 22:45:00.772060685 +0000
1456@@ -46,6 +46,7 @@
1457
1458 #if defined (READLINE)
1459 # include "bashline.h"
1460+# include <readline/readline.h>
1461 #endif
1462
1463 #if defined (HISTORY)
1464@@ -62,6 +63,7 @@
1465 #if defined (HISTORY)
1466 extern int history_lines_this_session;
1467 #endif
1468+extern int no_line_editing;
1469
1470 extern void initialize_siglist ();
1471
1472@@ -505,7 +507,10 @@
1473 {
1474 #if defined (HISTORY)
1475 /* XXX - will inhibit history file being written */
1476- history_lines_this_session = 0;
1477+# if defined (READLINE)
1478+ if (interactive_shell == 0 || interactive == 0 || (sig != SIGHUP && sig != SIGTERM) || no_line_editing || (RL_ISSTATE (RL_STATE_READCMD) == 0))
1479+# endif
1480+ history_lines_this_session = 0;
1481 #endif
1482 terminate_immediately = 0;
1483 termsig_handler (sig);
1484diff -Naur bash-4.2.orig/subst.c bash-4.2/subst.c
1485--- bash-4.2.orig/subst.c 2011-01-02 21:12:51.000000000 +0000
1486+++ bash-4.2/subst.c 2012-11-04 22:45:01.018726663 +0000
1487@@ -366,6 +366,11 @@
1488 f &= ~W_ASSNBLTIN;
1489 fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
1490 }
1491+ if (f & W_ASSNGLOBAL)
1492+ {
1493+ f &= ~W_ASSNGLOBAL;
1494+ fprintf (stderr, "W_ASSNGLOBAL%s", f ? "|" : "");
1495+ }
1496 if (f & W_COMPASSIGN)
1497 {
1498 f &= ~W_COMPASSIGN;
1499@@ -1379,10 +1384,12 @@
1500 slen = strlen (string + *sindex) + *sindex;
1501
1502 /* The handling of dolbrace_state needs to agree with the code in parse.y:
1503- parse_matched_pair() */
1504- dolbrace_state = 0;
1505- if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1506- dolbrace_state = (flags & SX_POSIXEXP) ? DOLBRACE_QUOTE : DOLBRACE_PARAM;
1507+ parse_matched_pair(). The different initial value is to handle the
1508+ case where this function is called to parse the word in
1509+ ${param op word} (SX_WORD). */
1510+ dolbrace_state = (flags & SX_WORD) ? DOLBRACE_WORD : DOLBRACE_PARAM;
1511+ if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && (flags & SX_POSIXEXP))
1512+ dolbrace_state = DOLBRACE_QUOTE;
1513
1514 i = *sindex;
1515 while (c = string[i])
1516@@ -2801,7 +2808,7 @@
1517 }
1518 else if (assign_list)
1519 {
1520- if (word->flags & W_ASSIGNARG)
1521+ if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL) == 0)
1522 aflags |= ASS_MKLOCAL;
1523 if (word->flags & W_ASSIGNASSOC)
1524 aflags |= ASS_MKASSOC;
1525@@ -3371,7 +3378,7 @@
1526 if (string == 0 || *string == '\0')
1527 return (WORD_LIST *)NULL;
1528
1529- td.flags = 0;
1530+ td.flags = W_NOSPLIT2; /* no splitting, remove "" and '' */
1531 td.word = string;
1532 tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
1533 return (tresult);
1534@@ -3704,7 +3711,10 @@
1535 break;
1536 }
1537 else if (string[i] == CTLNUL)
1538- i++;
1539+ {
1540+ i++;
1541+ continue;
1542+ }
1543
1544 prev_i = i;
1545 ADVANCE_CHAR (string, slen, i);
1546@@ -4156,7 +4166,7 @@
1547 simple = (wpat[0] != L'\\' && wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'[');
1548 #if defined (EXTENDED_GLOB)
1549 if (extended_glob)
1550- simple |= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
1551+ simple &= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
1552 #endif
1553
1554 /* If the pattern doesn't match anywhere in the string, go ahead and
1555@@ -4607,6 +4617,7 @@
1556 if (ifs_firstc == 0)
1557 #endif
1558 word->flags |= W_NOSPLIT;
1559+ word->flags |= W_NOSPLIT2;
1560 result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
1561 expand_no_split_dollar_star = 0;
1562
1563@@ -5798,6 +5809,16 @@
1564 is the only expansion that creates more than one word. */
1565 if (qdollaratp && ((hasdol && quoted) || l->next))
1566 *qdollaratp = 1;
1567+ /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
1568+ a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the
1569+ flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the
1570+ expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1571+ (which is more paranoia than anything else), we need to return the
1572+ quoted null string and set the flags to indicate it. */
1573+ if (l->next == 0 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL(temp) && QUOTED_NULL(l->word->word) && (l->word->flags & W_HASQUOTEDNULL))
1574+ {
1575+ w->flags |= W_HASQUOTEDNULL;
1576+ }
1577 dispose_words (l);
1578 }
1579 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
1580@@ -7176,7 +7197,7 @@
1581 {
1582 /* Extract the contents of the ${ ... } expansion
1583 according to the Posix.2 rules. */
1584- value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#') ? SX_POSIXEXP : 0);
1585+ value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#' || c =='/' || c == '^' || c == ',' || c ==':') ? SX_POSIXEXP|SX_WORD : SX_WORD);
1586 if (string[sindex] == RBRACE)
1587 sindex++;
1588 else
1589@@ -7268,6 +7289,7 @@
1590 default:
1591 case '\0':
1592 bad_substitution:
1593+ last_command_exit_value = EXECUTION_FAILURE;
1594 report_error (_("%s: bad substitution"), string ? string : "??");
1595 FREE (value);
1596 FREE (temp);
1597@@ -7900,7 +7922,7 @@
1598
1599 /* State flags */
1600 int had_quoted_null;
1601- int has_dollar_at;
1602+ int has_dollar_at, temp_has_dollar_at;
1603 int tflag;
1604 int pflags; /* flags passed to param_expand */
1605
1606@@ -8105,13 +8127,14 @@
1607 if (expanded_something)
1608 *expanded_something = 1;
1609
1610- has_dollar_at = 0;
1611+ temp_has_dollar_at = 0;
1612 pflags = (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0;
1613 if (word->flags & W_NOSPLIT2)
1614 pflags |= PF_NOSPLIT2;
1615 tword = param_expand (string, &sindex, quoted, expanded_something,
1616- &has_dollar_at, &quoted_dollar_at,
1617+ &temp_has_dollar_at, &quoted_dollar_at,
1618 &had_quoted_null, pflags);
1619+ has_dollar_at += temp_has_dollar_at;
1620
1621 if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
1622 {
1623@@ -8129,6 +8152,14 @@
1624 temp = tword->word;
1625 dispose_word_desc (tword);
1626
1627+ /* Kill quoted nulls; we will add them back at the end of
1628+ expand_word_internal if nothing else in the string */
1629+ if (had_quoted_null && temp && QUOTED_NULL (temp))
1630+ {
1631+ FREE (temp);
1632+ temp = (char *)NULL;
1633+ }
1634+
1635 goto add_string;
1636 break;
1637
1638@@ -8244,9 +8275,10 @@
1639
1640 temp = (char *)NULL;
1641
1642- has_dollar_at = 0;
1643+ temp_has_dollar_at = 0; /* XXX */
1644 /* Need to get W_HASQUOTEDNULL flag through this function. */
1645- list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
1646+ list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &temp_has_dollar_at, (int *)NULL);
1647+ has_dollar_at += temp_has_dollar_at;
1648
1649 if (list == &expand_word_error || list == &expand_word_fatal)
1650 {
1651@@ -8533,7 +8565,7 @@
1652 tword->flags |= W_NOEXPAND; /* XXX */
1653 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1654 tword->flags |= W_QUOTED;
1655- if (had_quoted_null)
1656+ if (had_quoted_null && QUOTED_NULL (istring))
1657 tword->flags |= W_HASQUOTEDNULL;
1658 list = make_word_list (tword, (WORD_LIST *)NULL);
1659 }
1660@@ -8564,7 +8596,7 @@
1661 tword->flags |= W_NOGLOB;
1662 if (word->flags & W_NOEXPAND)
1663 tword->flags |= W_NOEXPAND;
1664- if (had_quoted_null)
1665+ if (had_quoted_null && QUOTED_NULL (istring))
1666 tword->flags |= W_HASQUOTEDNULL; /* XXX */
1667 list = make_word_list (tword, (WORD_LIST *)NULL);
1668 }
1669diff -Naur bash-4.2.orig/subst.h bash-4.2/subst.h
1670--- bash-4.2.orig/subst.h 2010-12-03 01:21:29.000000000 +0000
1671+++ bash-4.2/subst.h 2012-11-04 22:45:00.715394173 +0000
1672@@ -56,6 +56,7 @@
1673 #define SX_NOLONGJMP 0x0040 /* don't longjmp on fatal error */
1674 #define SX_ARITHSUB 0x0080 /* extracting $(( ... )) (currently unused) */
1675 #define SX_POSIXEXP 0x0100 /* extracting new Posix pattern removal expansions in extract_dollar_brace_string */
1676+#define SX_WORD 0x0200 /* extracting word in ${param op word} */
1677
1678 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1679 STRING, and returns a pointer to it. */
1680diff -Naur bash-4.2.orig/support/shobj-conf bash-4.2/support/shobj-conf
1681--- bash-4.2.orig/support/shobj-conf 2009-10-28 13:20:21.000000000 +0000
1682+++ bash-4.2/support/shobj-conf 2012-11-04 22:45:00.808727251 +0000
1683@@ -157,7 +157,7 @@
1684 ;;
1685
1686 # Darwin/MacOS X
1687-darwin[89]*|darwin10*)
1688+darwin[89]*|darwin1[012]*)
1689 SHOBJ_STATUS=supported
1690 SHLIB_STATUS=supported
1691
1692@@ -186,7 +186,7 @@
1693 SHLIB_LIBSUFF='dylib'
1694
1695 case "${host_os}" in
1696- darwin[789]*|darwin10*) SHOBJ_LDFLAGS=''
1697+ darwin[789]*|darwin1[012]*) SHOBJ_LDFLAGS=''
1698 SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
1699 ;;
1700 *) SHOBJ_LDFLAGS='-dynamic'
1701diff -Naur bash-4.2.orig/tests/shopt.right bash-4.2/tests/shopt.right
1702--- bash-4.2.orig/tests/shopt.right 2010-07-03 03:36:30.000000000 +0000
1703+++ bash-4.2/tests/shopt.right 2012-11-04 22:45:00.858727113 +0000
1704@@ -12,6 +12,7 @@
1705 shopt -u compat32
1706 shopt -u compat40
1707 shopt -u compat41
1708+shopt -u direxpand
1709 shopt -u dirspell
1710 shopt -u dotglob
1711 shopt -u execfail
1712@@ -68,6 +69,7 @@
1713 shopt -u compat32
1714 shopt -u compat40
1715 shopt -u compat41
1716+shopt -u direxpand
1717 shopt -u dirspell
1718 shopt -u dotglob
1719 shopt -u execfail
1720@@ -101,6 +103,7 @@
1721 compat32 off
1722 compat40 off
1723 compat41 off
1724+direxpand off
1725 dirspell off
1726 dotglob off
1727 execfail off
1728diff -Naur bash-4.2.orig/variables.c bash-4.2/variables.c
1729--- bash-4.2.orig/variables.c 2011-01-25 01:07:48.000000000 +0000
1730+++ bash-4.2/variables.c 2012-11-04 22:45:00.765394035 +0000
1731@@ -3653,6 +3653,22 @@
1732 return n;
1733 }
1734
1735+int
1736+chkexport (name)
1737+ char *name;
1738+{
1739+ SHELL_VAR *v;
1740+
1741+ v = find_variable (name);
1742+ if (v && exported_p (v))
1743+ {
1744+ array_needs_making = 1;
1745+ maybe_make_export_env ();
1746+ return 1;
1747+ }
1748+ return 0;
1749+}
1750+
1751 void
1752 maybe_make_export_env ()
1753 {
1754@@ -4214,7 +4230,7 @@
1755 { "TEXTDOMAIN", sv_locale },
1756 { "TEXTDOMAINDIR", sv_locale },
1757
1758-#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
1759+#if defined (HAVE_TZSET)
1760 { "TZ", sv_tz },
1761 #endif
1762
1763@@ -4558,12 +4574,13 @@
1764 }
1765 #endif /* HISTORY */
1766
1767-#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
1768+#if defined (HAVE_TZSET)
1769 void
1770 sv_tz (name)
1771 char *name;
1772 {
1773- tzset ();
1774+ if (chkexport (name))
1775+ tzset ();
1776 }
1777 #endif
1778
1779diff -Naur bash-4.2.orig/variables.h bash-4.2/variables.h
1780--- bash-4.2.orig/variables.h 2010-12-03 01:22:01.000000000 +0000
1781+++ bash-4.2/variables.h 2012-11-04 22:45:00.755394063 +0000
1782@@ -313,6 +313,7 @@
1783
1784 extern void sort_variables __P((SHELL_VAR **));
1785
1786+extern int chkexport __P((char *));
1787 extern void maybe_make_export_env __P((void));
1788 extern void update_export_env_inplace __P((char *, int, char *));
1789 extern void put_command_name_into_env __P((char *));
Note: See TracBrowser for help on using the repository browser.