source: patches/bash-4.0-branch_update-6.patch@ 92bb2cbe

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since 92bb2cbe was 8e00734, checked in by Jim Gifford <clfs@…>, 15 years ago

Updated Bash Branch Update Patch

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