source: patches/bash-4.2-branch_update-5.patch@ 8833783

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

Update bash 4.2 to patch level 37.

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