source: patches/bash-4.0-branch_update-7.patch@ 5e4b3b4

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since 5e4b3b4 was 28428e9, checked in by jim <jim@…>, 15 years ago

Updated Bash Patch

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