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

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since 7c0efc5 was 140d857, checked in by Jim Gifford <clfs@…>, 16 years ago

Updated Bash Update Patch to 5

  • Property mode set to 100644
File size: 34.2 KB
RevLine 
[c822ddc]1Submitted By: Jim Gifford (jim at cross-lfs dot org)
[140d857]2Date: 05-24-2009
[c822ddc]3Initial Package Version: 4.0
4Origin: Upstream
5Upstream Status: Applied
[140d857]6Description: Contains all upstream patches up to 4.0-024
[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
[140d857]10+++ bash-4.0/arrayfunc.c 2009-05-24 09:14:10.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
[140d857]79+++ bash-4.0/builtins/declare.def 2009-05-24 09:14:07.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
[140d857]105+++ bash-4.0/builtins/exit.def 2009-05-24 09:14:06.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
[140d857]117+++ bash-4.0/builtins/fc.def 2009-05-24 09:14:20.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
[140d857]183+++ bash-4.0/builtins/read.def 2009-05-24 09:14:13.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);
[e6b4db2]204diff -Naur bash-4.0.orig/execute_cmd.c bash-4.0/execute_cmd.c
205--- bash-4.0.orig/execute_cmd.c 2009-02-13 13:41:41.000000000 -0800
[140d857]206+++ bash-4.0/execute_cmd.c 2009-05-24 09:14:23.000000000 -0700
[e6b4db2]207@@ -568,6 +568,7 @@
208
209 /* Fork a subshell, turn off the subshell bit, turn off job
210 control and call execute_command () on the command again. */
211+ line_number_for_err_trap = line_number;
212 paren_pid = make_child (savestring (make_command_string (command)),
213 asynchronous);
214 if (paren_pid == 0)
215@@ -610,7 +611,10 @@
216 if (user_subshell && was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
217 {
218 last_command_exit_value = exec_result;
219+ save_line_number = line_number;
220+ line_number = line_number_for_err_trap;
221 run_error_trap ();
222+ line_number = save_line_number;
223 }
224
225 if (user_subshell && ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
226@@ -766,7 +770,9 @@
227 if (was_error_trap && ignore_return == 0 && invert == 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS)
228 {
229 last_command_exit_value = exec_result;
230+ line_number = line_number_for_err_trap;
231 run_error_trap ();
232+ line_number = save_line_number;
233 }
234
235 if (ignore_return == 0 && invert == 0 &&
236@@ -2105,6 +2111,7 @@
237 REDIRECT *rp;
238 COMMAND *tc, *second;
239 int ignore_return, exec_result, was_error_trap, invert;
240+ volatile int save_line_number;
241
242 ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
243
244@@ -2174,12 +2181,16 @@
245 invert = (command->flags & CMD_INVERT_RETURN) != 0;
246 ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
247
248+ line_number_for_err_trap = line_number;
249 exec_result = execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close);
250
251 if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS)
252 {
253 last_command_exit_value = exec_result;
254+ save_line_number = line_number;
255+ line_number = line_number_for_err_trap;
256 run_error_trap ();
257+ line_number = save_line_number;
258 }
259
260 if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS)
261@@ -2930,7 +2941,7 @@
262 retval = execute_command (clauses->action);
263 }
264 while ((clauses->flags & CASEPAT_FALLTHROUGH) && (clauses = clauses->next));
265- if ((clauses->flags & CASEPAT_TESTNEXT) == 0)
266+ if (clauses == 0 || (clauses->flags & CASEPAT_TESTNEXT) == 0)
267 EXIT_CASE ();
268 else
269 break;
[140d857]270diff -Naur bash-4.0.orig/jobs.c bash-4.0/jobs.c
271--- bash-4.0.orig/jobs.c 2009-01-29 14:09:49.000000000 -0800
272+++ bash-4.0/jobs.c 2009-05-24 09:14:28.000000000 -0700
273@@ -442,7 +442,7 @@
274 old_pipeline = the_pipeline;
275 the_pipeline = saved_pipeline;
276 already_making_children = saved_already_making_children;
277- if (discard)
278+ if (discard && old_pipeline)
279 discard_pipeline (old_pipeline);
280 }
281
282@@ -4202,4 +4202,23 @@
283 sh_closepipe (pgrp_pipe);
284 }
285
286+void
287+save_pgrp_pipe (p, clear)
288+ int *p;
289+ int clear;
290+{
291+ p[0] = pgrp_pipe[0];
292+ p[1] = pgrp_pipe[1];
293+ if (clear)
294+ pgrp_pipe[0] = pgrp_pipe[1] = -1;
295+}
296+
297+void
298+restore_pgrp_pipe (p)
299+ int *p;
300+{
301+ pgrp_pipe[0] = p[0];
302+ pgrp_pipe[1] = p[1];
303+}
304+
305 #endif /* PGRP_PIPE */
306diff -Naur bash-4.0.orig/jobs.h bash-4.0/jobs.h
307--- bash-4.0.orig/jobs.h 2009-01-04 11:32:29.000000000 -0800
308+++ bash-4.0/jobs.h 2009-05-24 09:14:28.000000000 -0700
309@@ -235,6 +235,8 @@
310 extern void init_job_stats __P((void));
311
312 extern void close_pgrp_pipe __P((void));
313+extern void save_pgrp_pipe __P((int *, int));
314+extern void restore_pgrp_pipe __P((int *));
315
316 #if defined (JOB_CONTROL)
317 extern int job_control;
318diff -Naur bash-4.0.orig/lib/glob/glob.c bash-4.0/lib/glob/glob.c
319--- bash-4.0.orig/lib/glob/glob.c 2009-01-04 11:32:30.000000000 -0800
320+++ bash-4.0/lib/glob/glob.c 2009-05-24 09:14:36.000000000 -0700
321@@ -356,7 +356,7 @@
322 *np = 0;
323 if (ep)
324 *ep = 0;
325- if (r)
326+ if (r && r != &glob_error_return)
327 free (r);
328 return (struct globval *)0;
329 }
330@@ -665,8 +665,9 @@
331 (void) closedir (d);
332 }
333
334- /* compat: if GX_ALLDIRS, add the passed directory also */
335- if (add_current)
336+ /* compat: if GX_ALLDIRS, add the passed directory also, but don't add an
337+ empty directory name. */
338+ if (add_current && (flags & GX_NULLDIR) == 0)
339 {
340 sdlen = strlen (dir);
341 nextname = (char *)malloc (sdlen + 1);
342@@ -678,10 +679,7 @@
343 nextlink->name = nextname;
344 nextlink->next = lastlink;
345 lastlink = nextlink;
346- if (flags & GX_NULLDIR)
347- nextname[0] = '\0';
348- else
349- bcopy (dir, nextname, sdlen + 1);
350+ bcopy (dir, nextname, sdlen + 1);
351 ++count;
352 }
353 }
354@@ -942,7 +940,12 @@
355 char **array;
356 register unsigned int l;
357
358- array = glob_dir_to_array (directories[i], temp_results, flags);
359+ /* If we're expanding **, we don't need to glue the directory
360+ name to the results; we've already done it in glob_vector */
361+ if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
362+ array = temp_results;
363+ else
364+ array = glob_dir_to_array (directories[i], temp_results, flags);
365 l = 0;
366 while (array[l] != NULL)
367 ++l;
368@@ -959,7 +962,8 @@
369 result[result_size - 1] = NULL;
370
371 /* Note that the elements of ARRAY are not freed. */
372- free ((char *) array);
373+ if (array != temp_results)
374+ free ((char *) array);
375 }
376 }
377 /* Free the directories. */
378diff -Naur bash-4.0.orig/lib/readline/display.c bash-4.0/lib/readline/display.c
379--- bash-4.0.orig/lib/readline/display.c 2009-01-04 11:32:32.000000000 -0800
380+++ bash-4.0/lib/readline/display.c 2009-05-24 09:14:34.000000000 -0700
381@@ -512,6 +512,7 @@
382 /* Block keyboard interrupts because this function manipulates global
383 data structures. */
384 _rl_block_sigint ();
385+ RL_SETSTATE (RL_STATE_REDISPLAYING);
386
387 if (!rl_display_prompt)
388 rl_display_prompt = "";
389@@ -1236,6 +1237,7 @@
390 visible_wrap_offset = wrap_offset;
391 }
392
393+ RL_UNSETSTATE (RL_STATE_REDISPLAYING);
394 _rl_release_sigint ();
395 }
396
397@@ -1772,7 +1774,7 @@
398 space_to_eol will insert too many spaces. XXX - maybe we should
399 adjust col_lendiff based on the difference between _rl_last_c_pos
400 and _rl_screenwidth */
401- if (col_lendiff && (_rl_last_c_pos < _rl_screenwidth))
402+ if (col_lendiff && ((MB_CUR_MAX == 1 || rl_byte_oriented) || (_rl_last_c_pos < _rl_screenwidth)))
403 #endif
404 {
405 if (_rl_term_autowrap && current_line < inv_botlin)
406@@ -1892,6 +1894,10 @@
407
408 woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
409 cpos = _rl_last_c_pos;
410+
411+ if (cpos == 0 && cpos == new)
412+ return;
413+
414 #if defined (HANDLE_MULTIBYTE)
415 /* If we have multibyte characters, NEW is indexed by the buffer point in
416 a multibyte string, but _rl_last_c_pos is the display position. In
417@@ -1905,9 +1911,9 @@
418 prompt string, since they're both buffer indices and DPOS is a
419 desired display position. */
420 if ((new > prompt_last_invisible) || /* XXX - don't use woff here */
421- (prompt_physical_chars > _rl_screenwidth &&
422+ (prompt_physical_chars >= _rl_screenwidth &&
423 _rl_last_v_pos == prompt_last_screen_line &&
424- wrap_offset >= woff &&
425+ wrap_offset >= woff && dpos >= woff &&
426 new > (prompt_last_invisible-(_rl_screenwidth*_rl_last_v_pos)-wrap_offset)))
427 /* XXX last comparison might need to be >= */
428 {
429diff -Naur bash-4.0.orig/lib/readline/readline.h bash-4.0/lib/readline/readline.h
430--- bash-4.0.orig/lib/readline/readline.h 2009-01-04 11:32:33.000000000 -0800
431+++ bash-4.0/lib/readline/readline.h 2009-05-24 09:14:30.000000000 -0700
432@@ -814,8 +814,9 @@
433 #define RL_STATE_VIMOTION 0x100000 /* reading vi motion arg */
434 #define RL_STATE_MULTIKEY 0x200000 /* reading multiple-key command */
435 #define RL_STATE_VICMDONCE 0x400000 /* entered vi command mode at least once */
436+#define RL_STATE_REDISPLAYING 0x800000 /* updating terminal display */
437
438-#define RL_STATE_DONE 0x800000 /* done; accepted line */
439+#define RL_STATE_DONE 0x1000000 /* done; accepted line */
440
441 #define RL_SETSTATE(x) (rl_readline_state |= (x))
442 #define RL_UNSETSTATE(x) (rl_readline_state &= ~(x))
443diff -Naur bash-4.0.orig/lib/readline/terminal.c bash-4.0/lib/readline/terminal.c
444--- bash-4.0.orig/lib/readline/terminal.c 2009-01-04 11:32:34.000000000 -0800
445+++ bash-4.0/lib/readline/terminal.c 2009-05-24 09:14:30.000000000 -0700
446@@ -355,7 +355,7 @@
447 _rl_get_screen_size (fileno (rl_instream), 1);
448 if (CUSTOM_REDISPLAY_FUNC ())
449 rl_forced_update_display ();
450- else
451+ else if (RL_ISSTATE(RL_STATE_REDISPLAYING) == 0)
452 _rl_redisplay_after_sigwinch ();
453 }
454 }
455diff -Naur bash-4.0.orig/lib/sh/winsize.c bash-4.0/lib/sh/winsize.c
456--- bash-4.0.orig/lib/sh/winsize.c 2008-08-12 10:53:51.000000000 -0700
457+++ bash-4.0/lib/sh/winsize.c 2009-05-24 09:14:27.000000000 -0700
458@@ -30,16 +30,29 @@
459
460 #include <sys/ioctl.h>
461
462-#if !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
463-/* For struct winsize on SCO */
464-/* sys/ptem.h has winsize but needs mblk_t from sys/stream.h */
465-# if defined (HAVE_SYS_PTEM_H) && defined (TIOCGWINSZ) && defined (SIGWINCH)
466-# if defined (HAVE_SYS_STREAM_H)
467-# include <sys/stream.h>
468-# endif
469+/* Try to find the definitions of `struct winsize' and TIOGCWINSZ */
470+
471+#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
472+# include <sys/ioctl.h>
473+#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
474+
475+#if defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
476+# include <termios.h>
477+#endif /* STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */
478+
479+/* Not in either of the standard places, look around. */
480+#if !defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
481+# if defined (HAVE_SYS_STREAM_H)
482+# include <sys/stream.h>
483+# endif /* HAVE_SYS_STREAM_H */
484+# if defined (HAVE_SYS_PTEM_H) /* SVR4.2, at least, has it here */
485 # include <sys/ptem.h>
486-# endif /* HAVE_SYS_PTEM_H && TIOCGWINSZ && SIGWINCH */
487-#endif /* !STRUCT_WINSIZE_IN_SYS_IOCTL */
488+# define _IO_PTEM_H /* work around SVR4.2 1.1.4 bug */
489+# endif /* HAVE_SYS_PTEM_H */
490+# if defined (HAVE_SYS_PTE_H) /* ??? */
491+# include <sys/pte.h>
492+# endif /* HAVE_SYS_PTE_H */
493+#endif /* !STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */
494
495 #include <stdio.h>
496
[c822ddc]497diff -Naur bash-4.0.orig/parse.y bash-4.0/parse.y
498--- bash-4.0.orig/parse.y 2009-01-08 05:29:12.000000000 -0800
[140d857]499+++ bash-4.0/parse.y 2009-05-24 09:14:32.000000000 -0700
[e6b4db2]500@@ -1122,7 +1122,7 @@
501 REDIRECTEE rd;
502 REDIRECT *r;
503
504- tc = $1;
505+ tc = $1->type == cm_simple ? (COMMAND *)$1->value.Simple : $1;
506 rd.dest = 1;
507 r = make_redirection (2, r_duplicating_output, rd);
508 if (tc->redirects)
[c822ddc]509@@ -1615,10 +1615,11 @@
510 {
511 int *ret;
512
513- ret = (int *)xmalloc (3 * sizeof (int));
514+ ret = (int *)xmalloc (4 * sizeof (int));
515 ret[0] = last_read_token;
516 ret[1] = token_before_that;
517 ret[2] = two_tokens_ago;
518+ ret[3] = current_token;
519 return ret;
520 }
521
522@@ -1631,6 +1632,7 @@
523 last_read_token = ts[0];
524 token_before_that = ts[1];
525 two_tokens_ago = ts[2];
526+ current_token = ts[3];
527 }
528
529 /*
[e6b4db2]530@@ -1877,7 +1879,7 @@
531 prompt_again ();
532 ret = read_a_line (remove_quoted_newline);
533 #if defined (HISTORY)
534- if (remember_on_history && (parser_state & PST_HEREDOC))
535+ if (ret && remember_on_history && (parser_state & PST_HEREDOC))
536 {
537 /* To make adding the the here-document body right, we need to rely
538 on history_delimiting_chars() returning \n for the first line of
[c822ddc]539@@ -2668,6 +2670,7 @@
540 FREE (word_desc_to_read);
541 word_desc_to_read = (WORD_DESC *)NULL;
542
543+ current_token = '\n'; /* XXX */
544 last_read_token = '\n';
545 token_to_read = '\n';
546 }
547@@ -2915,6 +2918,7 @@
548 #define P_DQUOTE 0x04
549 #define P_COMMAND 0x08 /* parsing a command, so look for comments */
550 #define P_BACKQUOTE 0x10 /* parsing a backquoted command substitution */
551+#define P_ARRAYSUB 0x20 /* parsing a [...] array subscript for assignment */
552
553 /* Lexical state while parsing a grouping construct or $(...). */
554 #define LEX_WASDOL 0x001
[973b90d5]555@@ -2927,6 +2931,7 @@
556 #define LEX_INHEREDOC 0x080
557 #define LEX_HEREDELIM 0x100 /* reading here-doc delimiter */
558 #define LEX_STRIPDOC 0x200 /* <<- strip tabs from here doc delim */
559+#define LEX_INWORD 0x400
560
561 #define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|')
562
563@@ -3129,6 +3134,8 @@
[c822ddc]564 APPEND_NESTRET ();
565 FREE (nestret);
566 }
567+ else if ((flags & P_ARRAYSUB) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
568+ goto parse_dollar_word;
569 }
570 /* Parse an old-style command substitution within double quotes as a
571 single word. */
[973b90d5]572@@ -3145,6 +3152,7 @@
[c822ddc]573 else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
574 /* check for $(), $[], or ${} inside quoted string. */
575 {
576+parse_dollar_word:
577 if (open == ch) /* undo previous increment */
578 count--;
579 if (ch == '(') /* ) */
[973b90d5]580@@ -3179,7 +3187,7 @@
581 int open, close;
582 int *lenp, flags;
583 {
584- int count, ch, peekc, tflags, lex_rwlen, lex_firstind;
585+ int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
586 int nestlen, ttranslen, start_lineno;
587 char *ret, *nestret, *ttrans, *heredelim;
588 int retind, retsize, rflags, hdlen;
589@@ -3200,7 +3208,7 @@
590 retind = 0;
591
592 start_lineno = line_number;
593- lex_rwlen = 0;
594+ lex_rwlen = lex_wlen = 0;
595
596 heredelim = 0;
597 lex_firstind = -1;
598@@ -3267,6 +3275,46 @@
599 continue;
[c822ddc]600 }
601
[973b90d5]602+ if (tflags & LEX_PASSNEXT) /* last char was backslash */
603+ {
604+/*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
605+ tflags &= ~LEX_PASSNEXT;
606+ if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
607+ {
608+ if (retind > 0)
609+ retind--; /* swallow previously-added backslash */
610+ continue;
611+ }
612+
613+ RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
614+ if MBTEST(ch == CTLESC || ch == CTLNUL)
615+ ret[retind++] = CTLESC;
616+ ret[retind++] = ch;
617+ continue;
618+ }
619+
620+ /* If this is a shell break character, we are not in a word. If not,
621+ we either start or continue a word. */
622+ if MBTEST(shellbreak (ch))
623+ {
624+ tflags &= ~LEX_INWORD;
625+/*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
626+ }
627+ else
628+ {
629+ if (tflags & LEX_INWORD)
630+ {
631+ lex_wlen++;
632+/*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
633+ }
634+ else
635+ {
636+/*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
637+ tflags |= LEX_INWORD;
638+ lex_wlen = 0;
639+ }
640+ }
641+
642 /* Skip whitespace */
643 if MBTEST(shellblank (ch) && lex_rwlen == 0)
644 {
[140d857]645@@ -3306,7 +3354,7 @@
646 }
647
648 /* Meta-characters that can introduce a reserved word. Not perfect yet. */
649- if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && shellmeta(ch))
650+ if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && (shellmeta(ch) || ch == '\n'))
651 {
652 /* Add this character. */
653 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
[973b90d5]654@@ -3364,9 +3412,21 @@
655 }
656 tflags &= ~LEX_RESWDOK;
657 }
658- else if (shellbreak (ch) == 0)
659+ else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
660+ ; /* don't modify LEX_RESWDOK if we're starting a comment */
661+ else if MBTEST((tflags & LEX_INCASE) && ch != '\n')
662+ /* If we can read a reserved word and we're in case, we're at the
663+ point where we can read a new pattern list or an esac. We
664+ handle the esac case above. If we read a newline, we want to
665+ leave LEX_RESWDOK alone. If we read anything else, we want to
666+ turn off LEX_RESWDOK, since we're going to read a pattern list. */
667 {
668- tflags &= ~LEX_RESWDOK;
669+ tflags &= ~LEX_RESWDOK;
670+/*itrace("parse_comsub:%d: lex_incase == 1 found `%c', lex_reswordok -> 0", line_number, ch);*/
671+}
672+ else if MBTEST(shellbreak (ch) == 0)
673+{
674+ tflags &= ~LEX_RESWDOK;
675 /*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
676 }
677 }
678@@ -3394,36 +3454,23 @@
[c822ddc]679 }
680 else
681 shell_ungetc (peekc);
682- tflags |= LEX_HEREDELIM;
683- lex_firstind = -1;
684+ if (peekc != '<')
685+ {
686+ tflags |= LEX_HEREDELIM;
687+ lex_firstind = -1;
688+ }
689 continue;
690 }
691 else
[973b90d5]692- ch = peekc; /* fall through and continue XXX - this skips comments if peekc == '#' */
693+ ch = peekc; /* fall through and continue XXX */
694 }
695- /* Not exactly right yet, should handle shell metacharacters, too. If
696- any changes are made to this test, make analogous changes to subst.c:
697- extract_delimited_string(). */
698- else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
699+ else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
700+{
701+/*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
702 tflags |= LEX_INCOMMENT;
703+}
704
705- if (tflags & LEX_PASSNEXT) /* last char was backslash */
706- {
707- tflags &= ~LEX_PASSNEXT;
708- if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
709- {
710- if (retind > 0)
711- retind--; /* swallow previously-added backslash */
712- continue;
713- }
714-
715- RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
716- if MBTEST(ch == CTLESC || ch == CTLNUL)
717- ret[retind++] = CTLESC;
718- ret[retind++] = ch;
719- continue;
720- }
721- else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
722+ if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
723 {
724 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
725 ret[retind++] = CTLESC;
726@@ -4248,7 +4295,7 @@
[c822ddc]727 ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
728 (token_index == 0 && (parser_state&PST_COMPASSIGN))))
729 {
730- ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
731+ ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
732 if (ttok == &matched_pair_error)
733 return -1; /* Bail immediately. */
734 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
[973b90d5]735@@ -4449,6 +4496,7 @@
[c822ddc]736 case '}': /* XXX */
737 case AND_AND:
738 case BANG:
739+ case BAR_AND:
740 case DO:
741 case DONE:
742 case ELIF:
[973b90d5]743diff -Naur bash-4.0.orig/patchlevel.h bash-4.0/patchlevel.h
744--- bash-4.0.orig/patchlevel.h 2009-01-04 11:32:40.000000000 -0800
[140d857]745+++ bash-4.0/patchlevel.h 2009-05-24 09:14:36.000000000 -0700
[973b90d5]746@@ -25,6 +25,6 @@
747 regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
748 looks for to find the patch level (for the sccs version string). */
749
750-#define PATCHLEVEL 0
[140d857]751+#define PATCHLEVEL 24
[973b90d5]752
753 #endif /* _PATCHLEVEL_H_ */
[c822ddc]754diff -Naur bash-4.0.orig/pcomplete.c bash-4.0/pcomplete.c
755--- bash-4.0.orig/pcomplete.c 2009-02-01 14:12:31.000000000 -0800
[140d857]756+++ bash-4.0/pcomplete.c 2009-05-24 09:14:02.000000000 -0700
[c822ddc]757@@ -1032,6 +1032,7 @@
758 cmdlist = build_arg_list (funcname, text, lwords, cw);
759
760 pps = &ps;
761+ save_parser_state (pps);
762 begin_unwind_frame ("gen-shell-function-matches");
763 add_unwind_protect (restore_parser_state, (char *)pps);
764 add_unwind_protect (dispose_words, (char *)cmdlist);
[e6b4db2]765diff -Naur bash-4.0.orig/sig.c bash-4.0/sig.c
766--- bash-4.0.orig/sig.c 2009-01-04 11:32:41.000000000 -0800
[140d857]767+++ bash-4.0/sig.c 2009-05-24 09:14:22.000000000 -0700
[e6b4db2]768@@ -448,6 +448,48 @@
769 termsig_sighandler (sig)
770 int sig;
771 {
772+ /* If we get called twice with the same signal before handling it,
773+ terminate right away. */
774+ if (
775+#ifdef SIGHUP
776+ sig != SIGHUP &&
777+#endif
778+#ifdef SIGINT
779+ sig != SIGINT &&
780+#endif
781+#ifdef SIGDANGER
782+ sig != SIGDANGER &&
783+#endif
784+#ifdef SIGPIPE
785+ sig != SIGPIPE &&
786+#endif
787+#ifdef SIGALRM
788+ sig != SIGALRM &&
789+#endif
790+#ifdef SIGTERM
791+ sig != SIGTERM &&
792+#endif
793+#ifdef SIGXCPU
794+ sig != SIGXCPU &&
795+#endif
796+#ifdef SIGXFSZ
797+ sig != SIGXFSZ &&
798+#endif
799+#ifdef SIGVTALRM
800+ sig != SIGVTALRM &&
801+#endif
802+#ifdef SIGLOST
803+ sig != SIGLOST &&
804+#endif
805+#ifdef SIGUSR1
806+ sig != SIGUSR1 &&
807+#endif
808+#ifdef SIGUSR2
809+ sig != SIGUSR2 &&
810+#endif
811+ sig == terminating_signal)
812+ terminate_immediately = 1;
813+
814 terminating_signal = sig;
815
816 /* XXX - should this also trigger when interrupt_immediately is set? */
[c822ddc]817diff -Naur bash-4.0.orig/subst.c bash-4.0/subst.c
818--- bash-4.0.orig/subst.c 2009-01-28 11:34:12.000000000 -0800
[140d857]819+++ bash-4.0/subst.c 2009-05-24 09:14:19.000000000 -0700
[e6b4db2]820@@ -85,6 +85,7 @@
821
822 /* Flags for the `pflags' argument to param_expand() */
823 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
824+#define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */
825
826 /* These defs make it easier to use the editor. */
827 #define LBRACE '{'
828@@ -222,6 +223,7 @@
[c822ddc]829 static int skip_double_quoted __P((char *, size_t, int));
830 static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
831 static char *extract_dollar_brace_string __P((char *, int *, int, int));
832+static int skip_matched_pair __P((const char *, int, int, int, int));
833
834 static char *pos_params __P((char *, int, int, int));
835
[e6b4db2]836@@ -262,7 +264,7 @@
837 static int chk_atstar __P((char *, int, int *, int *));
838 static int chk_arithsub __P((const char *, int));
839
840-static WORD_DESC *parameter_brace_expand_word __P((char *, int, int));
841+static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int));
842 static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
843 static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
844 static void parameter_brace_expand_error __P((char *, char *));
845@@ -1374,6 +1376,107 @@
[c822ddc]846
847 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
848
849+/* This function assumes s[i] == open; returns with s[ret] == close; used to
850+ parse array subscripts. FLAGS currently unused. */
851+static int
852+skip_matched_pair (string, start, open, close, flags)
853+ const char *string;
854+ int start, open, close, flags;
855+{
856+ int i, pass_next, backq, si, c, count;
857+ size_t slen;
858+ char *temp, *ss;
859+ DECLARE_MBSTATE;
860+
861+ slen = strlen (string + start) + start;
862+ no_longjmp_on_fatal_error = 1;
863+
864+ i = start + 1; /* skip over leading bracket */
865+ count = 1;
866+ pass_next = backq = 0;
867+ ss = (char *)string;
868+ while (c = string[i])
869+ {
870+ if (pass_next)
871+ {
872+ pass_next = 0;
873+ if (c == 0)
874+ CQ_RETURN(i);
875+ ADVANCE_CHAR (string, slen, i);
876+ continue;
877+ }
878+ else if (c == '\\')
879+ {
880+ pass_next = 1;
881+ i++;
882+ continue;
883+ }
884+ else if (backq)
885+ {
886+ if (c == '`')
887+ backq = 0;
888+ ADVANCE_CHAR (string, slen, i);
889+ continue;
890+ }
891+ else if (c == '`')
892+ {
893+ backq = 1;
894+ i++;
895+ continue;
896+ }
897+ else if (c == open)
898+ {
899+ count++;
900+ i++;
901+ continue;
902+ }
903+ else if (c == close)
904+ {
905+ count--;
906+ if (count == 0)
907+ break;
908+ i++;
909+ continue;
910+ }
911+ else if (c == '\'' || c == '"')
912+ {
913+ i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
914+ : skip_double_quoted (ss, slen, ++i);
915+ /* no increment, the skip functions increment past the closing quote. */
916+ }
917+ else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
918+ {
919+ si = i + 2;
920+ if (string[si] == '\0')
921+ CQ_RETURN(si);
922+
923+ if (string[i+1] == LPAREN)
924+ temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
925+ else
926+ temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
927+ i = si;
928+ if (string[i] == '\0') /* don't increment i past EOS in loop */
929+ break;
930+ i++;
931+ continue;
932+ }
933+ else
934+ ADVANCE_CHAR (string, slen, i);
935+ }
936+
937+ CQ_RETURN(i);
938+}
939+
940+#if defined (ARRAY_VARS)
941+int
942+skipsubscript (string, start)
943+ const char *string;
944+ int start;
945+{
946+ return (skip_matched_pair (string, start, '[', ']', 0));
947+}
948+#endif
949+
950 /* Skip characters in STRING until we find a character in DELIMS, and return
951 the index of that character. START is the index into string at which we
952 begin. This is similar in spirit to strpbrk, but it returns an index into
[e6b4db2]953@@ -5093,9 +5196,9 @@
954 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
955 NAME was found inside of a double-quoted expression. */
956 static WORD_DESC *
957-parameter_brace_expand_word (name, var_is_special, quoted)
958+parameter_brace_expand_word (name, var_is_special, quoted, pflags)
959 char *name;
960- int var_is_special, quoted;
961+ int var_is_special, quoted, pflags;
962 {
963 WORD_DESC *ret;
964 char *temp, *tt;
965@@ -5127,7 +5230,7 @@
966 strcpy (tt + 1, name);
967
968 ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
969- (int *)NULL, (int *)NULL, 0);
970+ (int *)NULL, (int *)NULL, pflags);
971 free (tt);
972 }
973 #if defined (ARRAY_VARS)
974@@ -5188,7 +5291,7 @@
975 char *temp, *t;
976 WORD_DESC *w;
977
978- w = parameter_brace_expand_word (name, var_is_special, quoted);
979+ w = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
980 t = w->word;
981 /* Have to dequote here if necessary */
982 if (t)
983@@ -5205,7 +5308,7 @@
984 if (t == 0)
985 return (WORD_DESC *)NULL;
986
987- w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted);
988+ w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted, 0);
989 free (t);
990
991 return w;
992@@ -6556,7 +6659,7 @@
993 if (want_indir)
994 tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
995 else
996- tdesc = parameter_brace_expand_word (name, var_is_special, quoted);
997+ tdesc = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND);
998
999 if (tdesc)
1000 {
1001@@ -6887,7 +6990,7 @@
1002 case '*': /* `$*' */
1003 list = list_rest_of_args ();
1004
1005- if (list == 0 && unbound_vars_is_error)
1006+ if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
1007 {
1008 uerror[0] = '$';
1009 uerror[1] = '*';
1010@@ -6949,7 +7052,7 @@
1011 case '@': /* `$@' */
1012 list = list_rest_of_args ();
1013
1014- if (list == 0 && unbound_vars_is_error)
1015+ if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
1016 {
1017 uerror[0] = '$';
1018 uerror[1] = '@';
1019diff -Naur bash-4.0.orig/trap.c bash-4.0/trap.c
1020--- bash-4.0.orig/trap.c 2009-01-16 14:07:53.000000000 -0800
[140d857]1021+++ bash-4.0/trap.c 2009-05-24 09:14:28.000000000 -0700
[e6b4db2]1022@@ -755,7 +755,7 @@
1023 }
1024
1025 flags = SEVAL_NONINT|SEVAL_NOHIST;
1026- if (sig != DEBUG_TRAP && sig != RETURN_TRAP)
1027+ if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP)
1028 flags |= SEVAL_RESETLINE;
1029 if (function_code == 0)
1030 parse_and_execute (trap_command, tag, flags);
[140d857]1031@@ -798,12 +798,36 @@
1032 run_debug_trap ()
1033 {
1034 int trap_exit_value;
1035+ pid_t save_pgrp;
1036+ int save_pipe[2];
1037
1038 /* XXX - question: should the DEBUG trap inherit the RETURN trap? */
1039 trap_exit_value = 0;
1040 if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && ((sigmodes[DEBUG_TRAP] & SIG_IGNORED) == 0) && ((sigmodes[DEBUG_TRAP] & SIG_INPROGRESS) == 0))
1041 {
1042+#if defined (JOB_CONTROL)
1043+ save_pgrp = pipeline_pgrp;
1044+ pipeline_pgrp = 0;
1045+ save_pipeline (1);
1046+# if defined (PGRP_PIPE)
1047+ save_pgrp_pipe (save_pipe, 1);
1048+# endif
1049+ stop_making_children ();
1050+#endif
1051+
1052 trap_exit_value = _run_trap_internal (DEBUG_TRAP, "debug trap");
1053+
1054+#if defined (JOB_CONTROL)
1055+ pipeline_pgrp = save_pgrp;
1056+ restore_pipeline (1);
1057+# if defined (PGRP_PIPE)
1058+ close_pgrp_pipe ();
1059+ restore_pgrp_pipe (save_pipe);
1060+# endif
1061+ if (pipeline_pgrp > 0)
1062+ give_terminal_to (pipeline_pgrp, 1);
1063+ notify_and_cleanup ();
1064+#endif
1065
1066 #if defined (DEBUGGER)
1067 /* 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.