From: Chet Ramey Date: Fri, 7 Dec 2012 16:06:21 +0000 (-0500) Subject: commit bash-20121119 snapshot X-Git-Tag: bash-4.3-alpha~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0500de0b2dc35884e8c228002a526b21fef60626;p=thirdparty%2Fbash.git commit bash-20121119 snapshot --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index e60dfedb5..5bfb07f4c 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -3829,3 +3829,64 @@ execute_cmd.c FIFOs reported by Zev Weiss - execute_null_command: do the same thing in the parent branch after make_child + + 11/14 + ----- +subst.c + - parameter_brace_expand: a variable is null if it's special ($@, $*), + the expansion occurs within double quotes, and the expansion turns + into a quoted null. Fixes debian bug 692447 reported by + Matrosov Dmitriy + +jobs.c + - run_sigchld_trap: make sure `running_trap' sentinel is set + appropriately + - waitchld: only run the sigchld trap if we're not in a signal + handler, not running a trap, and executing the wait builtin. + Otherwise, queue for later handling. We still run one instance + of the trap handler per exited child. Bulk of fix for bug + reported by Elliott Forney + +trap.c + - queue_sigchld_trap: set catch_flag so run_pending_traps notices, + and set trapped_signal_received for completeness. Rest of fix + for bug reported by Elliott Forney + +lib/malloc/malloc.c + - block_signals: renamed to _malloc_block_signals, made public + - unblock_signals: renamed to _malloc_unblock_signals, made public + +lib/malloc/imalloc.h + - extern declarations for _malloc_{un,}block_signals + +lib/malloc/table.c + - mregister_alloc, mregister_free: block signals around table + manipulation + + 11/15 + ----- +trap.c + - run_pending_traps: set SIG_INPROGRESS flag around calls to + run_sigchld_handler so other parts of the shell know that the + SIGCHLD trap handler is executing + - run_pending_traps: if we get a situation where we are looking at + running a SIGCHLD trap but the trap string is IMPOSSIBLE_TRAP_HANDLER + and the SIG_INPROGRESS flag is set, just skip it. This is possible + if run_pending_traps is called from a SIGCHLD trap handler run by + run_sigchld_trap + +doc/bash.1,lib/readline/doc/{rluser.texi,readline.3} + - corrected description of the effect of `set history-size 0'. Report + from Vesa-Matti J Kari + +include/stdc.h + - CPP_STRING: new define, replaces __STRING + +lib/malloc/{malloc.c,imalloc.h} + - replace __STRING with CPP_STRING + + 11/16 + ----- +lib/readline/bind.c + - sv_histsize: if argument evaluates to a value < 0, unstifle the + history diff --git a/MANIFEST b/MANIFEST index ffd10f428..63d77a88e 100644 --- a/MANIFEST +++ b/MANIFEST @@ -866,6 +866,7 @@ tests/dollar-star2.sub f tests/dollar-star3.sub f tests/dollar-star4.sub f tests/dollar-star5.sub f +tests/dollar-star6.sub f tests/dollar.right f tests/dstack.tests f tests/dstack.right f diff --git a/doc/bash.1 b/doc/bash.1 index ce7c4466e..f6461c8cc 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -5,12 +5,12 @@ .\" Case Western Reserve University .\" chet@po.cwru.edu .\" -.\" Last Change: Sun Oct 7 17:59:28 EDT 2012 +.\" Last Change: Thu Nov 15 21:03:47 EST 2012 .\" .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ .if \n(zY=1 .ig zY -.TH BASH 1 "2012 October 7" "GNU Bash 4.2" +.TH BASH 1 "2012 November 15" "GNU Bash 4.2" .\" .\" There's some problem with having a `@' .\" in a tagged paragraph with the BSD man macros. @@ -5337,8 +5337,12 @@ same location on each history line retrieved with \fBprevious-history\fP or \fBnext-history\fP. .TP .B history\-size (0) -Set the maximum number of history entries saved in the history list. If -set to zero, the number of entries in the history list is not limited. +Set the maximum number of history entries saved in the history list. +If set to zero, any existing history entries are deleted and no new entries +are saved. +If set to a value less than zero, the number of history entries is not +limited. +By default, the number of history entries is not limited. .TP .B horizontal\-scroll\-mode (Off) When set to \fBOn\fP, makes readline use a single line for display, diff --git a/include/stdc.h b/include/stdc.h index df01d813f..d2fd4b258 100644 --- a/include/stdc.h +++ b/include/stdc.h @@ -36,10 +36,11 @@ # endif #endif +/* Fortify, at least, has trouble with this definition */ #if defined (HAVE_STRINGIZE) -# define __STRING(x) #x +# define CPP_STRING(x) #x #else -# define __STRING(x) "x" +# define CPP_STRING(x) "x" #endif #if !defined (__STDC__) diff --git a/jobs.c b/jobs.c index bb0425833..a786d7048 100644 --- a/jobs.c +++ b/jobs.c @@ -933,10 +933,12 @@ realloc_jobs_list () } #if defined (DEBUG) +# if 0 itrace ("realloc_jobs_list: resize jobs list from %d to %d", js.j_jobslots, nsize); itrace ("realloc_jobs_list: j_lastj changed from %d to %d", js.j_lastj, (j > 0) ? j - 1 : 0); itrace ("realloc_jobs_list: j_njobs changed from %d to %d", js.j_njobs, j); itrace ("realloc_jobs_list: js.j_ndead %d js.c_reaped %d", js.j_ndead, js.c_reaped); +# endif #endif js.j_firstj = 0; @@ -964,7 +966,7 @@ realloc_jobs_list () reset_current (); #ifdef DEBUG - itrace ("realloc_jobs_list: reset js.j_current (%d) and js.j_previous (%d)", js.j_current, js.j_previous); +/* itrace ("realloc_jobs_list: reset js.j_current (%d) and js.j_previous (%d)", js.j_current, js.j_previous);*/ #endif UNBLOCK_CHILD (oset); @@ -987,7 +989,7 @@ compact_jobs_list (flags) realloc_jobs_list (); #ifdef DEBUG - itrace("compact_jobs_list: returning %d", (js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0); +/* itrace("compact_jobs_list: returning %d", (js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0); */ #endif return ((js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0); @@ -3235,10 +3237,17 @@ waitchld (wpid, block) if (sigchld == 0) longjmp (wait_intr_buf, 1); } + /* If not in posix mode and not executing the wait builtin, queue the + signal for later handling. Run the trap immediately if we are + executing the wait builtin, but don't break out of `wait'. */ else if (sigchld) /* called from signal handler */ queue_sigchld_trap (children_exited); - else + else if (running_trap) + queue_sigchld_trap (children_exited); + else if (this_shell_builtin == wait_builtin) run_sigchld_trap (children_exited); + else + queue_sigchld_trap (children_exited); } /* We have successfully recorded the useful information about this process @@ -3489,6 +3498,8 @@ run_sigchld_trap (nchild) subst_assign_varlist = (WORD_LIST *)NULL; the_pipeline = (PROCESS *)NULL; + running_trap = SIGCHLD + 1; + set_impossible_sigchld_trap (); jobs_list_frozen = 1; for (i = 0; i < nchild; i++) @@ -3498,6 +3509,7 @@ run_sigchld_trap (nchild) } run_unwind_frame ("SIGCHLD trap"); + running_trap = 0; } /* Function to call when you want to notify people of changes diff --git a/lib/malloc/imalloc.h b/lib/malloc/imalloc.h index 34df10af9..82b09eba0 100644 --- a/lib/malloc/imalloc.h +++ b/lib/malloc/imalloc.h @@ -45,11 +45,11 @@ # define NULL 0 #endif -#if !defined (__STRING) +#if !defined (CPP_STRING) # if defined (HAVE_STRINGIZE) -# define __STRING(x) #x +# define CPP_STRING(x) #x # else -# define __STRING(x) "x" +# define CPP_STRING(x) "x" # endif /* !HAVE_STRINGIZE */ #endif /* !__STRING */ @@ -165,4 +165,9 @@ do { \ # define _(x) x #endif +#include + +extern void _malloc_block_signals __P((sigset_t *, sigset_t *)); +extern void _malloc_unblock_signals __P((sigset_t *, sigset_t *)); + #endif /* _IMALLOC_H */ diff --git a/lib/malloc/malloc.c b/lib/malloc/malloc.c index c67fde054..1c92ca67b 100644 --- a/lib/malloc/malloc.c +++ b/lib/malloc/malloc.c @@ -172,7 +172,7 @@ typedef union _malloc_guard { #define ASSERT(p) \ do \ { \ - if (!(p)) xbotch((PTR_T)0, ERR_ASSERT_FAILED, __STRING(p), file, line); \ + if (!(p)) xbotch((PTR_T)0, ERR_ASSERT_FAILED, CPP_STRING(p), file, line); \ } \ while (0) @@ -265,7 +265,7 @@ extern char *sbrk (); #endif /* !HAVE_DECL_SBRK */ #ifdef SHELL -extern int interrupt_immediately; +extern int interrupt_immediately, running_trap; extern int signal_is_trapped __P((int)); #endif @@ -498,8 +498,8 @@ xsplit (mp, nu) busy[nbuck] = 0; } -static void -block_signals (setp, osetp) +void +_malloc_block_signals (setp, osetp) sigset_t *setp, *osetp; { #ifdef HAVE_POSIX_SIGNALS @@ -513,8 +513,8 @@ block_signals (setp, osetp) #endif } -static void -unblock_signals (setp, osetp) +void +_malloc_unblock_signals (setp, osetp) sigset_t *setp, *osetp; { #ifdef HAVE_POSIX_SIGNALS @@ -562,10 +562,10 @@ morecore (nu) /* Block all signals in case we are executed from a signal handler. */ blocked_sigs = 0; #ifdef SHELL - if (interrupt_immediately || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD)) + if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD)) #endif { - block_signals (&set, &oset); + _malloc_block_signals (&set, &oset); blocked_sigs = 1; } @@ -652,7 +652,7 @@ morecore (nu) morecore_done: if (blocked_sigs) - unblock_signals (&set, &oset); + _malloc_unblock_signals (&set, &oset); } static void diff --git a/lib/malloc/table.c b/lib/malloc/table.c index cf89b3c0e..f0e2c1e31 100644 --- a/lib/malloc/table.c +++ b/lib/malloc/table.c @@ -28,6 +28,11 @@ #include "imalloc.h" #include "table.h" +#ifdef SHELL +extern int interrupt_immediately, running_trap; +extern int signal_is_trapped __P((int)); +#endif + extern int malloc_register; #ifdef MALLOC_REGISTER @@ -168,6 +173,18 @@ mregister_alloc (tag, mem, size, file, line) int line; { mr_table_t *tentry; + sigset_t set, oset; + int blocked_sigs; + + /* Block all signals in case we are executed from a signal handler. */ + blocked_sigs = 0; +#ifdef SHELL + if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD)) +#endif + { + _malloc_block_signals (&set, &oset); + blocked_sigs = 1; + } tentry = find_entry (mem, FIND_ALLOC); @@ -175,6 +192,8 @@ mregister_alloc (tag, mem, size, file, line) { /* oops. table is full. punt. */ fprintf (stderr, _("register_alloc: alloc table is full with FIND_ALLOC?\n")); + if (blocked_sigs) + _malloc_unblock_signals (&set, &oset); return; } @@ -194,6 +213,9 @@ mregister_alloc (tag, mem, size, file, line) if (tentry != &mem_overflow) table_allocated++; + + if (blocked_sigs) + _malloc_unblock_signals (&set, &oset); } void @@ -204,6 +226,18 @@ mregister_free (mem, size, file, line) int line; { mr_table_t *tentry; + sigset_t set, oset; + int blocked_sigs; + + /* Block all signals in case we are executed from a signal handler. */ + blocked_sigs = 0; +#ifdef SHELL + if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD)) +#endif + { + _malloc_block_signals (&set, &oset); + blocked_sigs = 1; + } tentry = find_entry (mem, FIND_EXIST); if (tentry == 0) @@ -212,6 +246,8 @@ mregister_free (mem, size, file, line) #if 0 fprintf (stderr, "register_free: %p not in allocation table?\n", mem); #endif + if (blocked_sigs) + _malloc_unblock_signals (&set, &oset); return; } if (tentry->flags & MT_FREE) @@ -228,6 +264,9 @@ mregister_free (mem, size, file, line) if (tentry != &mem_overflow) table_allocated--; + + if (blocked_sigs) + _malloc_unblock_signals (&set, &oset); } /* If we ever add more flags, this will require changes. */ diff --git a/lib/readline/bind.c b/lib/readline/bind.c index 1d008cb23..10bc71144 100644 --- a/lib/readline/bind.c +++ b/lib/readline/bind.c @@ -1752,7 +1752,10 @@ sv_histsize (value) { nval = atoi (value); if (nval < 0) - return 1; + { + unstifle_history (); + return 0; + } } stifle_history (nval); return 0; diff --git a/lib/readline/doc/readline.3 b/lib/readline/doc/readline.3 index e180b31a2..06116511c 100644 --- a/lib/readline/doc/readline.3 +++ b/lib/readline/doc/readline.3 @@ -6,9 +6,9 @@ .\" Case Western Reserve University .\" chet@ins.CWRU.Edu .\" -.\" Last Change: Sat Aug 28 18:56:32 EDT 2010 +.\" Last Change: Thu Nov 15 21:02:20 EST 2012 .\" -.TH READLINE 3 "2010 August 28" "GNU Readline 6.2" +.TH READLINE 3 "2012 November 15" "GNU Readline 6.2" .\" .\" File Name macro. This used to be `.PN', for Path Name, .\" but Sun doesn't seem to like that very much. @@ -445,8 +445,12 @@ same location on each history line retrieved with \fBprevious-history\fP or \fBnext-history\fP. .TP .B history\-size (0) -Set the maximum number of history entries saved in the history list. If -set to zero, the number of entries in the history list is not limited. +Set the maximum number of history entries saved in the history list. +If set to zero, any existing history entries are deleted and no new entries +are saved. +If set to a value less than zero, the number of history entries is not +limited. +By default, the number of history entries is not limited. .TP .B horizontal\-scroll\-mode (Off) When set to \fBOn\fP, makes readline use a single line for display, diff --git a/lib/readline/doc/rluser.texi b/lib/readline/doc/rluser.texi index 9efb3f5a5..93ea3c048 100644 --- a/lib/readline/doc/rluser.texi +++ b/lib/readline/doc/rluser.texi @@ -531,8 +531,12 @@ or @code{next-history}. The default is @samp{off}. @item history-size @vindex history-size -Set the maximum number of history entries saved in the history list. If -set to zero, the number of entries in the history list is not limited. +Set the maximum number of history entries saved in the history list. +If set to zero, any existing history entries are deleted and no new entries +are saved. +If set to a value less than zero, the number of history entries is not +limited. +By default, the number of history entries is not limited. @item horizontal-scroll-mode @vindex horizontal-scroll-mode diff --git a/lib/readline/doc/version.texi b/lib/readline/doc/version.texi index 0a285c0b4..ba5446529 100644 --- a/lib/readline/doc/version.texi +++ b/lib/readline/doc/version.texi @@ -4,7 +4,7 @@ Copyright (C) 1988-2012 Free Software Foundation, Inc. @set EDITION 6.2 @set VERSION 6.2 -@set UPDATED 23 September 2012 -@set UPDATED-MONTH September 2012 +@set UPDATED 15 November 2012 +@set UPDATED-MONTH November 2012 -@set LASTCHANGE Sun Sep 23 19:19:18 EDT 2012 +@set LASTCHANGE Thu Nov 15 21:03:04 EST 2012 diff --git a/subst.c b/subst.c index 1ec19580f..958c2619b 100644 --- a/subst.c +++ b/subst.c @@ -7268,6 +7268,9 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta var_is_set = temp != (char *)0; var_is_null = check_nullness && (var_is_set == 0 || *temp == 0); + /* XXX - this may not need to be restricted to special variables */ + if (check_nullness) + var_is_null |= var_is_special && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL (temp); /* Get the rest of the stuff inside the braces. */ if (c && c != RBRACE) diff --git a/tests/dollar-at-star b/tests/dollar-at-star index ad858386e..bf95fec18 100755 --- a/tests/dollar-at-star +++ b/tests/dollar-at-star @@ -242,4 +242,7 @@ ${THIS_SH} ./dollar-at4.sub # through bash-4.2 ${THIS_SH} ./dollar-at5.sub +# tests for expansions of $* when $1 == ""; problem through bash-4.2 +${THIS_SH} ./dollar-star6.sub + exit 0 diff --git a/tests/dollar-star6.sub b/tests/dollar-star6.sub new file mode 100644 index 000000000..5f8dea915 --- /dev/null +++ b/tests/dollar-star6.sub @@ -0,0 +1,5 @@ +set -- "" + +recho "A${*:-w}R" +recho "A${*-w}R" +recho "A${*}R" diff --git a/tests/dollar.right b/tests/dollar.right index de940c1cb..4a5c3891b 100644 --- a/tests/dollar.right +++ b/tests/dollar.right @@ -225,3 +225,6 @@ ${@:2}c$1 c2 c3 #works as long as quoting omitted set y zcx c2 c3 0 declare -a c='([0]="y" [1]="zcx" [2]="c2" [3]="c3")' +argv[1] = +argv[1] = +argv[1] = diff --git a/trap.c b/trap.c index 457b659e4..a127d2182 100644 --- a/trap.c +++ b/trap.c @@ -313,7 +313,18 @@ run_pending_traps () trap_list[SIGCHLD] != (char *)IMPOSSIBLE_TRAP_HANDLER && (sigmodes[SIGCHLD] & SIG_INPROGRESS) == 0) { + sigmodes[SIGCHLD] |= SIG_INPROGRESS; run_sigchld_trap (pending_traps[sig]); /* use as counter */ + sigmodes[SIGCHLD] &= ~SIG_INPROGRESS; + } + else if (sig == SIGCHLD && + trap_list[SIGCHLD] == (char *)IMPOSSIBLE_TRAP_HANDLER && + (sigmodes[SIGCHLD] & SIG_INPROGRESS) != 0) + { + /* This can happen when run_pending_traps is called while + running a SIGCHLD trap handler. */ + UNBLOCK_SIGNAL (oset); + continue; /* XXX */ } #endif else if (trap_list[sig] == (char *)DEFAULT_SIG || @@ -404,7 +415,7 @@ trap_handler (sig) wait_signal_received = sig; if (interrupt_immediately) { -itrace("trap_handler: calling longjmp to wait_intr_buf: sig = %d", sig); +itrace("trap_handler: interrupt_immediately = 1: calling longjmp to wait_intr_buf: sig = %d", sig); longjmp (wait_intr_buf, 1); } } @@ -496,7 +507,11 @@ queue_sigchld_trap (nchild) int nchild; { if (nchild > 0) - pending_traps[SIGCHLD] += nchild; + { + catch_flag = 1; + pending_traps[SIGCHLD] += nchild; + trapped_signal_received = SIGCHLD; + } } #endif /* JOB_CONTROL && SIGCHLD */