mbox

bash: update to 4.3.30

Message ID 1464889428-6768-1-git-send-email-marcel.lorenz@ipfire.org
State Dropped
Headers

Message

Marcel Lorenz June 3, 2016, 3:43 a.m. UTC
  Old bash patches are removed

Signed-off-by: Marcel Lorenz <marcel.lorenz@ipfire.org>
---
 config/rootfiles/common/bash                   |  12 +
 lfs/bash                                       |  20 +-
 src/patches/bash-3.2-ssh_source_bash.patch     |  12 -
 src/patches/bash-4.0-paths-1.patch             |  11 -
 src/patches/bash-4.0-profile-1.patch           |  12 -
 src/patches/bash-4.3.30-upstream_fixes-3.patch | 488 +++++++++++++++++++++++++
 6 files changed, 505 insertions(+), 50 deletions(-)
 delete mode 100644 src/patches/bash-3.2-ssh_source_bash.patch
 delete mode 100644 src/patches/bash-4.0-paths-1.patch
 delete mode 100644 src/patches/bash-4.0-profile-1.patch
 create mode 100644 src/patches/bash-4.3.30-upstream_fixes-3.patch
  

Comments

Michael Tremer June 4, 2016, 1:20 a.m. UTC | #1
On Thu, 2016-06-02 at 19:43 +0200, Marcel Lorenz wrote:
> Old bash patches are removed

Why? We need those.

> 
> Signed-off-by: Marcel Lorenz <marcel.lorenz@ipfire.org>
> ---
>  config/rootfiles/common/bash                   |  12 +
>  lfs/bash                                       |  20 +-
>  src/patches/bash-3.2-ssh_source_bash.patch     |  12 -
>  src/patches/bash-4.0-paths-1.patch             |  11 -
>  src/patches/bash-4.0-profile-1.patch           |  12 -
>  src/patches/bash-4.3.30-upstream_fixes-3.patch | 488
> +++++++++++++++++++++++++
>  6 files changed, 505 insertions(+), 50 deletions(-)
>  delete mode 100644 src/patches/bash-3.2-ssh_source_bash.patch
>  delete mode 100644 src/patches/bash-4.0-paths-1.patch
>  delete mode 100644 src/patches/bash-4.0-profile-1.patch
>  create mode 100644 src/patches/bash-4.3.30-upstream_fixes-3.patch
> 
> diff --git a/config/rootfiles/common/bash b/config/rootfiles/common/bash
> index 84f587f..743a71a 100644
> --- a/config/rootfiles/common/bash
> +++ b/config/rootfiles/common/bash
> @@ -57,3 +57,15 @@ bin/bash
>  #usr/share/locale/zh_TW/LC_MESSAGES/bash.mo
>  #usr/share/man/man1/bash.1
>  #usr/share/man/man1/bashbug.1
> +#usr/share/doc/bash-4.3.30
> +#usr/share/doc/bash-4.3.30/CHANGES
> +#usr/share/doc/bash-4.3.30/COMPAT
> +#usr/share/doc/bash-4.3.30/FAQ
> +#usr/share/doc/bash-4.3.30/INTRO
> +#usr/share/doc/bash-4.3.30/NEWS
> +#usr/share/doc/bash-4.3.30/POSIX
> +#usr/share/doc/bash-4.3.30/RBASH
> +#usr/share/doc/bash-4.3.30/README
> +#usr/share/doc/bash-4.3.30/bash.html
> +#usr/share/doc/bash-4.3.30/bashref.html
> +
> diff --git a/lfs/bash b/lfs/bash
> index c215b5a..416b382 100644
> --- a/lfs/bash
> +++ b/lfs/bash
> @@ -24,7 +24,7 @@
>  
>  include Config
>  
> -VER        = 4.3
> +VER        = 4.3.30
>  
>  THISAPP    = bash-$(VER)
>  DL_FILE    = $(THISAPP).tar.gz
> @@ -43,7 +43,8 @@ else
>  endif
>  
>  CONFIGURE_OPTIONS += \
> -	--without-bash-malloc
> +	--without-bash-malloc \
> +	--docdir=/usr/share/doc/bash-4.3.30
>  
>  #############################################################################
> ##
>  # Top-level Rules
> @@ -53,7 +54,7 @@ objects = $(DL_FILE)
>  
>  $(DL_FILE)             = $(DL_FROM)/$(DL_FILE)
>  
> -$(DL_FILE)_MD5         = 81348932d5da294953e15d4814c74dd1
> +$(DL_FILE)_MD5         = a27b3ee9be83bd3ba448c0ff52b28447
>  
>  install : $(TARGET)
>  
> @@ -83,18 +84,7 @@ $(subst %,%_MD5,$(objects)) :
>  $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
>  	@$(PREBUILD)
>  	@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zaxf $(DIR_DL)/$(DL_FILE)
> -
> -	sed -e "s/filename, RTLD_LAZY/filename, RTLD_NOW/" \
> -		-i $(DIR_APP)/builtins/enable.def
> -
> -	for i in $$(seq 1 30); do \
> -		cd $(DIR_APP) && patch -Np0 <
> $(DIR_SRC)/src/patches/bash/bash43-$$(printf "%03d" "$${i}") || exit 1; \
> -	done
> -
> -	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash-4.0-paths-
> 1.patch
> -	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash-4.0-
> profile-1.patch
> -	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash-3.2-
> ssh_source_bash.patch
> -
> +	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash-4.3.30-
> upstream_fixes-3.patch
>  	cd $(DIR_APP) && ./configure $(CONFIGURE_OPTIONS)
>  	cd $(DIR_APP) && make $(MAKETUNING)
>  	cd $(DIR_APP) && make install
> diff --git a/src/patches/bash-3.2-ssh_source_bash.patch b/src/patches/bash-
> 3.2-ssh_source_bash.patch
> deleted file mode 100644
> index 5bd19ce..0000000
> --- a/src/patches/bash-3.2-ssh_source_bash.patch
> +++ /dev/null
> @@ -1,12 +0,0 @@
> -diff -up bash-4.0/config-top.h.ssh_source_bash bash-4.0/config-top.h
> ---- bash-4.0/config-top.h.ssh_source_bash	2009-01-21
> 15:20:06.000000000 +0100
> -+++ bash-4.0/config-top.h	2009-01-21 15:25:46.000000000 +0100
> -@@ -90,7 +90,7 @@
> -    sshd and source the .bashrc if so (like the rshd behavior).  This checks
> -    for the presence of SSH_CLIENT or SSH2_CLIENT in the initial environment,
> -    which can be fooled under certain not-uncommon circumstances. */
> --/* #define SSH_SOURCE_BASHRC */
> -+#define SSH_SOURCE_BASHRC
> - 
> - /* Define if you want the case-capitalizing operators (~[~]) and the
> -    `capcase' variable attribute (declare -c). */
> diff --git a/src/patches/bash-4.0-paths-1.patch b/src/patches/bash-4.0-paths-
> 1.patch
> deleted file mode 100644
> index 24ec5cc..0000000
> --- a/src/patches/bash-4.0-paths-1.patch
> +++ /dev/null
> @@ -1,11 +0,0 @@
> ---- bash-3.0/config-top.h.paths	2003-08-05 15:36:12.000000000 +0100
> -+++ bash-3.0/config-top.h	2004-07-28 09:36:27.117205637 +0100
> -@@ -66,7 +66,7 @@
> -    the Posix.2 confstr () function, or CS_PATH define are not present. */
> - #ifndef STANDARD_UTILS_PATH
> - #define STANDARD_UTILS_PATH \
> --  "/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc"
> -+  "/bin:/usr/bin:/usr/sbin:/sbin"
> - #endif
> - 
> - /* Default primary and secondary prompt strings. */
> diff --git a/src/patches/bash-4.0-profile-1.patch b/src/patches/bash-4.0-
> profile-1.patch
> deleted file mode 100644
> index ba3344b..0000000
> --- a/src/patches/bash-4.0-profile-1.patch
> +++ /dev/null
> @@ -1,12 +0,0 @@
> -diff -up bash-3.2/config-top.h.profile bash-3.2/config-top.h
> ---- bash-3.2/config-top.h.profile	2008-07-17 13:35:39.000000000 +0200
> -+++ bash-3.2/config-top.h	2008-07-17 13:42:18.000000000 +0200
> -@@ -26,6 +26,8 @@
> -    what POSIX.2 specifies. */
> - #define CONTINUE_AFTER_KILL_ERROR
> - 
> -+#define NON_INTERACTIVE_LOGIN_SHELLS
> -+
> - /* Define BREAK_COMPLAINS if you want the non-standard, but useful
> -    error messages about `break' and `continue' out of context. */
> - #define BREAK_COMPLAINS
> diff --git a/src/patches/bash-4.3.30-upstream_fixes-3.patch
> b/src/patches/bash-4.3.30-upstream_fixes-3.patch
> new file mode 100644
> index 0000000..459ce26
> --- /dev/null
> +++ b/src/patches/bash-4.3.30-upstream_fixes-3.patch
> @@ -0,0 +1,488 @@
> +Submitted By:            Armin K. <krejzi at email dot com>
> +Date:                    2016-02-16
> +Initial Package Version: 4.3
> +Upstream Status:         Already in upstream patch repo
> +Origin:                  Upstream
> +Description:             This patch contains upstream patch numbers 031 thru
> 042
> +
> +--- a/arrayfunc.c	2014-10-01 18:57:35.000000000 +0200
> ++++ b/arrayfunc.c	2015-09-06 22:57:56.328941059 +0200
> +@@ -404,6 +404,9 @@
> +       (*var->assign_func) (var, l->word->word, i, 0);
> +     else
> +       array_insert (a, i, l->word->word);
> ++
> ++  VUNSETATTR (var, att_invisible);	/* no longer invisible */
> ++
> +   return var;
> + }
> + 
> +@@ -634,6 +637,10 @@
> + 
> +   if (nlist)
> +     dispose_words (nlist);
> ++
> ++  if (var)
> ++    VUNSETATTR (var, att_invisible);	/* no longer invisible */
> ++
> +   return (var);
> + }
> + 
> +--- a/assoc.c	2011-11-05 21:39:05.000000000 +0100
> ++++ b/assoc.c	2015-09-06 22:57:56.328941059 +0200
> +@@ -436,6 +436,8 @@
> + #if 1
> + 	if (sh_contains_shell_metas (tlist->key))
> + 	  istr = sh_double_quote (tlist->key);
> ++	else if (ALL_ELEMENT_SUB (tlist->key[0]) && tlist->key[1] == '\0')
> ++	  istr = sh_double_quote (tlist->key);	
> + 	else
> + 	  istr = tlist->key;	
> + #else
> +--- a/bashline.c	2014-10-01 18:57:30.000000000 +0200
> ++++ b/bashline.c	2015-09-06 22:58:34.711768943 +0200
> +@@ -202,6 +202,7 @@
> + extern int last_command_exit_value;
> + extern int array_needs_making;
> + extern int posixly_correct, no_symbolic_links;
> ++extern int sigalrm_seen;
> + extern char *current_prompt_string, *ps1_prompt;
> + extern STRING_INT_ALIST word_token_alist[];
> + extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
> +@@ -1467,10 +1468,23 @@
> + 
> +       os = start;
> +       n = 0;
> ++      was_assignment = 0;
> +       s = find_cmd_start (os);
> +       e = find_cmd_end (end);
> +       do
> + 	{
> ++	  /* Don't read past the end of rl_line_buffer */
> ++	  if (s > rl_end)
> ++	    {
> ++	      s1 = s = e1;
> ++	      break;
> ++	    }
> ++	  /* Or past point if point is within an assignment statement */
> ++	  else if (was_assignment && s > rl_point)
> ++	    {
> ++	      s1 = s = e1;
> ++	      break;
> ++	    }
> + 	  /* Skip over assignment statements preceding a command name.  If
> we
> + 	     don't find a command name at all, we can perform command name
> + 	     completion.  If we find a partial command name, we should
> perform
> +@@ -4208,8 +4222,9 @@
> + {
> +   /* If we're going to longjmp to top_level, make sure we clean up readline.
> +      check_signals will call QUIT, which will eventually longjmp to
> top_level,
> +-     calling run_interrupt_trap along the way. */
> +-  if (interrupt_state)
> ++     calling run_interrupt_trap along the way.  The check for sigalrm_seen
> is
> ++     to clean up the read builtin's state. */
> ++  if (terminating_signal || interrupt_state || sigalrm_seen)
> +     rl_cleanup_after_signal ();
> +   bashline_reset_event_hook ();
> +   check_signals_and_traps ();	/* XXX */
> +--- a/builtins/common.h	2014-10-01 18:57:47.000000000 +0200
> ++++ b/builtins/common.h	2015-09-06 22:57:56.330941103 +0200
> +@@ -122,6 +122,10 @@
> + /* Functions from getopts.def */
> + extern void getopts_reset __P((int));
> + 
> ++/* Functions from read.def */
> ++extern void read_tty_cleanup __P((void));
> ++extern int read_tty_modified __P((void));
> ++
> + /* Functions from set.def */
> + extern int minus_o_option_value __P((char *));
> + extern void list_minus_o_opts __P((int, int));
> +--- a/builtins/read.def	2014-10-01 18:57:38.000000000 +0200
> ++++ b/builtins/read.def	2015-09-06 22:57:56.335941212 +0200
> +@@ -140,10 +140,12 @@
> + procenv_t alrmbuf;
> + int sigalrm_seen;
> + 
> +-static int reading;
> ++static int reading, tty_modified;
> + static SigHandler *old_alrm;
> + static unsigned char delim;
> + 
> ++static struct ttsave termsave;
> ++
> + /* In all cases, SIGALRM just sets a flag that we check periodically.  This
> +    avoids problems with the semi-tricky stuff we do with the xfree of
> +    input_string at the top of the unwind-protect list (see below). */
> +@@ -188,7 +190,6 @@
> +   struct stat tsb;
> +   SHELL_VAR *var;
> +   TTYSTRUCT ttattrs, ttset;
> +-  struct ttsave termsave;
> + #if defined (ARRAY_VARS)
> +   WORD_LIST *alist;
> + #endif
> +@@ -221,7 +222,7 @@
> +   USE_VAR(ps2);
> +   USE_VAR(lastsig);
> + 
> +-  sigalrm_seen = reading = 0;
> ++  sigalrm_seen = reading = tty_modified = 0;
> + 
> +   i = 0;		/* Index into the string that we are reading. */
> +   raw = edit = 0;	/* Not reading raw input by default. */
> +@@ -438,6 +439,8 @@
> + 	  retval = 128+SIGALRM;
> + 	  goto assign_vars;
> + 	}
> ++      if (interactive_shell == 0)
> ++	initialize_terminating_signals ();
> +       old_alrm = set_signal_handler (SIGALRM, sigalrm);
> +       add_unwind_protect (reset_alarm, (char *)NULL);
> + #if defined (READLINE)
> +@@ -482,7 +485,10 @@
> + 	  i = silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, &ttset);
> + 	  if (i < 0)
> + 	    sh_ttyerror (1);
> ++	  tty_modified = 1;
> + 	  add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
> ++	  if (interactive_shell == 0)
> ++	    initialize_terminating_signals ();
> + 	}
> +     }
> +   else if (silent)	/* turn off echo but leave term in canonical mode
> */
> +@@ -497,7 +503,10 @@
> +       if (i < 0)
> + 	sh_ttyerror (1);
> + 
> ++      tty_modified = 1;
> +       add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
> ++      if (interactive_shell == 0)
> ++	initialize_terminating_signals ();
> +     }
> + 
> +   /* This *must* be the top unwind-protect on the stack, so the manipulation
> +@@ -588,6 +597,8 @@
> + 	    }
> + 	  else
> + 	    lastsig = 0;
> ++	  if (terminating_signal && tty_modified)
> ++	    ttyrestore (&termsave);	/* fix terminal before exiting */
> + 	  CHECK_TERMSIG;
> + 	  eof = 1;
> + 	  break;
> +@@ -978,6 +989,20 @@
> +      struct ttsave *ttp;
> + {
> +   ttsetattr (ttp->fd, ttp->attrs);
> ++  tty_modified = 0;
> ++}
> ++
> ++void
> ++read_tty_cleanup ()
> ++{
> ++  if (tty_modified)
> ++    ttyrestore (&termsave);
> ++}
> ++
> ++int
> ++read_tty_modified ()
> ++{
> ++  return (tty_modified);
> + }
> + 
> + #if defined (READLINE)
> +--- a/builtins/set.def	2013-04-19 13:20:34.000000000 +0200
> ++++ b/builtins/set.def	2015-09-06 22:57:56.336941234 +0200
> +@@ -751,9 +751,11 @@
> +   WORD_LIST *list;
> + {
> +   int unset_function, unset_variable, unset_array, opt, nameref, any_failed;
> ++  int global_unset_func, global_unset_var;
> +   char *name;
> + 
> +   unset_function = unset_variable = unset_array = nameref = any_failed = 0;
> ++  global_unset_func = global_unset_var = 0;
> + 
> +   reset_internal_getopt ();
> +   while ((opt = internal_getopt (list, "fnv")) != -1)
> +@@ -761,10 +763,10 @@
> +       switch (opt)
> + 	{
> + 	case 'f':
> +-	  unset_function = 1;
> ++	  global_unset_func = 1;
> + 	  break;
> + 	case 'v':
> +-	  unset_variable = 1;
> ++	  global_unset_var = 1;
> + 	  break;
> + 	case 'n':
> + 	  nameref = 1;
> +@@ -777,7 +779,7 @@
> + 
> +   list = loptend;
> + 
> +-  if (unset_function && unset_variable)
> ++  if (global_unset_func && global_unset_var)
> +     {
> +       builtin_error (_("cannot simultaneously unset a function and a
> variable"));
> +       return (EXECUTION_FAILURE);
> +@@ -795,6 +797,9 @@
> + 
> +       name = list->word->word;
> + 
> ++      unset_function = global_unset_func;
> ++      unset_variable = global_unset_var;
> ++
> + #if defined (ARRAY_VARS)
> +       unset_array = 0;
> +       if (!unset_function && valid_array_reference (name))
> +--- a/jobs.c	2014-10-01 18:57:26.000000000 +0200
> ++++ b/jobs.c	2015-09-06 22:57:56.340941321 +0200
> +@@ -3339,7 +3339,9 @@
> +       if (posixly_correct && this_shell_builtin && this_shell_builtin ==
> wait_builtin)
> + 	{
> + 	  interrupt_immediately = 0;
> +-	  trap_handler (SIGCHLD);	/* set pending_traps[SIGCHLD] */
> ++	  /* This was trap_handler (SIGCHLD) but that can lose traps if
> ++	     children_exited > 1 */
> ++	  queue_sigchld_trap (children_exited);
> + 	  wait_signal_received = SIGCHLD;
> + 	  /* If we're in a signal handler, let CHECK_WAIT_INTR pick it up;
> + 	     run_pending_traps will call run_sigchld_trap later  */
> +--- a/lib/readline/complete.c	2013-10-14 15:27:10.000000000 +0200
> ++++ b/lib/readline/complete.c	2015-09-06 22:58:34.712768964 +0200
> +@@ -689,6 +689,8 @@
> + 
> +   if (temp == 0 || *temp == '\0')
> +     return (pathname);
> ++  else if (temp[1] == 0 && temp == pathname)
> ++    return (pathname);
> +   /* If the basename is NULL, we might have a pathname like '/usr/src/'.
> +      Look for a previous slash and, if one is found, return the portion
> +      following that slash.  If there's no previous slash, just return the
> +--- a/lib/sh/unicode.c	2014-01-30 22:47:19.000000000 +0100
> ++++ b/lib/sh/unicode.c	2015-09-06 22:57:56.341941343 +0200
> +@@ -78,13 +78,15 @@
> +   s = strrchr (locale, '.');
> +   if (s)
> +     {
> +-      strcpy (charsetbuf, s+1);
> ++      strncpy (charsetbuf, s+1, sizeof (charsetbuf) - 1);
> ++      charsetbuf[sizeof (charsetbuf) - 1] = '\0';
> +       t = strchr (charsetbuf, '@');
> +       if (t)
> + 	*t = 0;
> +       return charsetbuf;
> +     }
> +-  strcpy (charsetbuf, locale);
> ++  strncpy (charsetbuf, locale, sizeof (charsetbuf) - 1);
> ++  charsetbuf[sizeof (charsetbuf) - 1] = '\0';
> +   return charsetbuf;
> + }
> + #endif
> +--- a/parse.y	2014-10-05 19:52:50.000000000 +0200
> ++++ b/parse.y	2015-09-06 22:58:35.245780313 +0200
> +@@ -2818,11 +2818,16 @@
> +     case AND_AND:
> +     case OR_OR:
> +     case '&':
> ++    case WHILE:
> +     case DO:
> ++    case UNTIL:
> ++    case IF:
> +     case THEN:
> ++    case ELIF:
> +     case ELSE:
> +     case '{':		/* } */
> +-    case '(':		/* ) */
> ++    case '(':		/* )( */
> ++    case ')':		/* only valid in case statement */
> +     case BANG:		/* ! time pipeline */
> +     case TIME:		/* time time pipeline */
> +     case TIMEOPT:	/* time -p time pipeline */
> +@@ -3703,6 +3708,8 @@
> + /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch,
> __LINE__);*/
> + 	      tflags |= LEX_INWORD;
> + 	      lex_wlen = 0;
> ++	      if (tflags & LEX_RESWDOK)
> ++		lex_rwlen = 0;
> + 	    }
> + 	}
> + 
> +--- a/patchlevel.h	2014-10-05 19:52:50.000000000 +0200
> ++++ b/patchlevel.h	2015-09-06 22:58:35.248780377 +0200
> +@@ -25,6 +25,6 @@
> +    regexp `^#define[ 	]*PATCHLEVEL', since that's what
> support/mkversion.sh
> +    looks for to find the patch level (for the sccs version string). */
> + 
> +-#define PATCHLEVEL 30
> ++#define PATCHLEVEL 42
> + 
> + #endif /* _PATCHLEVEL_H_ */
> +--- a/shell.c	2014-01-14 14:04:32.000000000 +0100
> ++++ b/shell.c	2015-09-06 22:57:56.343941387 +0200
> +@@ -73,6 +73,7 @@
> + #endif
> + 
> + #if defined (READLINE)
> ++#  include <readline/readline.h>
> + #  include "bashline.h"
> + #endif
> + 
> +@@ -909,6 +910,14 @@
> +   fflush (stdout);		/* XXX */
> +   fflush (stderr);
> + 
> ++  /* Clean up the terminal if we are in a state where it's been modified. */
> ++#if defined (READLINE)
> ++  if (RL_ISSTATE (RL_STATE_TERMPREPPED) && rl_deprep_term_function)
> ++    (*rl_deprep_term_function) ();
> ++#endif
> ++  if (read_tty_modified ())
> ++    read_tty_cleanup ();
> ++
> +   /* Do trap[0] if defined.  Allow it to override the exit status
> +      passed to us. */
> +   if (signal_is_trapped (0))
> +--- a/sig.c	2014-01-10 21:06:06.000000000 +0100
> ++++ b/sig.c	2015-09-06 22:57:56.344941408 +0200
> +@@ -532,8 +532,10 @@
> + #if defined (READLINE)
> +   /* Set the event hook so readline will call it after the signal handlers
> +      finish executing, so if this interrupted character input we can get
> +-     quick response. */
> +-  if (interactive_shell && interactive && no_line_editing == 0)
> ++     quick response.  If readline is active or has modified the terminal we
> ++     need to set this no matter what the signal is, though the check for
> ++     RL_STATE_TERMPREPPED is possibly redundant. */
> ++  if (RL_ISSTATE (RL_STATE_SIGHANDLER) || RL_ISSTATE (RL_STATE_TERMPREPPED))
> +     bashline_set_event_hook ();
> + #endif
> + 
> +--- a/subst.c	2014-10-01 18:57:47.000000000 +0200
> ++++ b/subst.c	2015-09-06 22:58:34.177757570 +0200
> +@@ -5782,7 +5782,7 @@
> +       /* XXX - does this leak if name[@] or name[*]? */
> +       if (pflags & PF_ASSIGNRHS)
> +         {
> +-          temp = array_variable_name (name, &tt, (int *)0);
> ++          var = array_variable_part (name, &tt, (int *)0);
> +           if (ALL_ELEMENT_SUB (tt[0]) && tt[1] == ']')
> + 	    temp = array_value (name, quoted|Q_DOUBLE_QUOTES, 0, &atype,
> &ind);
> + 	  else
> +--- a/subst.h	2014-10-01 18:57:43.000000000 +0200
> ++++ b/subst.h	2015-09-06 22:57:56.344941408 +0200
> +@@ -47,6 +47,7 @@
> + #define ASS_MKASSOC	0x0004
> + #define ASS_MKGLOBAL	0x0008	/* force global assignment */
> + #define ASS_NAMEREF	0x0010	/* assigning to nameref variable */
> ++#define ASS_FROMREF	0x0020	/* assigning from value of nameref
> variable */
> + 
> + /* Flags for the string extraction functions. */
> + #define SX_NOALLOC	0x0001	/* just skip; don't return substring
> */
> +--- a/variables.c	2014-10-01 18:57:51.000000000 +0200
> ++++ b/variables.c	2015-09-06 22:57:56.345941430 +0200
> +@@ -2516,10 +2516,27 @@
> +      HASH_TABLE *table;
> +      int hflags, aflags;
> + {
> +-  char *newval;
> ++  char *newname, *newval;
> +   SHELL_VAR *entry;
> ++#if defined (ARRAY_VARS)
> ++  arrayind_t ind;
> ++  char *subp;
> ++  int sublen;
> ++#endif
> + 
> ++  newname = 0;
> ++#if defined (ARRAY_VARS)
> ++  if ((aflags & ASS_FROMREF) && (hflags & HASH_NOSRCH) == 0 &&
> valid_array_reference (name))
> ++    {
> ++      newname = array_variable_name (name, &subp, &sublen);
> ++      if (newname == 0)
> ++	return (SHELL_VAR *)NULL;	/* XXX */
> ++      entry = hash_lookup (newname, table);
> ++    }
> ++  else
> ++#endif
> +   entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name,
> table);
> ++
> +   /* Follow the nameref chain here if this is the global variables table */
> +   if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && table ==
> global_variables->table)
> +     {
> +@@ -2550,6 +2567,16 @@
> +       var_setvalue (entry, make_variable_value (entry, value, 0));
> +       }
> +     }
> ++#if defined (ARRAY_VARS)
> ++  else if (entry == 0 && newname)
> ++    {
> ++      entry = make_new_array_variable (newname);	/* indexed array by
> default */
> ++      if (entry == 0)
> ++	return entry;
> ++      ind = array_expand_index (name, subp, sublen);
> ++      bind_array_element (entry, ind, value, aflags);
> ++    }
> ++#endif
> +   else if (entry == 0)
> +     {
> +       entry = make_new_variable (name, table);
> +@@ -2670,7 +2697,8 @@
> + 			 normal. */
> + 		      if (nameref_cell (nv) == 0)
> + 			return (bind_variable_internal (nv->name, value,
> nvc->table, 0, flags));
> +-		      return (bind_variable_internal (nameref_cell (nv),
> value, nvc->table, 0, flags));
> ++		      /* XXX - bug here with ref=array[index] */
> ++		      return (bind_variable_internal (nameref_cell (nv),
> value, nvc->table, 0, flags|ASS_FROMREF));
> + 		    }
> + 		  else
> + 		    v = nv;
> +@@ -2805,10 +2833,12 @@
> + #endif
> +     v = bind_variable (lhs, rhs, 0);
> + 
> +-  if (v && isint)
> +-    VSETATTR (v, att_integer);
> +-
> +-  VUNSETATTR (v, att_invisible);
> ++  if (v)
> ++    {
> ++      if (isint)
> ++	VSETATTR (v, att_integer);
> ++      VUNSETATTR (v, att_invisible);
> ++    }
> + 
> +   return (v);
> + }
> +--- a/y.tab.c	2014-10-05 19:52:50.000000000 +0200
> ++++ b/y.tab.c	2015-09-06 22:58:35.247780356 +0200
> +@@ -5130,11 +5130,16 @@
> +     case AND_AND:
> +     case OR_OR:
> +     case '&':
> ++    case WHILE:
> +     case DO:
> ++    case UNTIL:
> ++    case IF:
> +     case THEN:
> ++    case ELIF:
> +     case ELSE:
> +     case '{':		/* } */
> +-    case '(':		/* ) */
> ++    case '(':		/* )( */
> ++    case ')':		/* only valid in case statement */
> +     case BANG:		/* ! time pipeline */
> +     case TIME:		/* time time pipeline */
> +     case TIMEOPT:	/* time -p time pipeline */
> +@@ -6015,6 +6020,8 @@
> + /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch,
> __LINE__);*/
> + 	      tflags |= LEX_INWORD;
> + 	      lex_wlen = 0;
> ++	      if (tflags & LEX_RESWDOK)
> ++		lex_rwlen = 0;
> + 	    }
> + 	}
> +
  
Marcel Lorenz June 4, 2016, 3:04 a.m. UTC | #2
Am 2016-06-03 17:20, schrieb Michael Tremer:
> On Thu, 2016-06-02 at 19:43 +0200, Marcel Lorenz wrote:
>> Old bash patches are removed
> 
> Why? We need those.

ok, for what? The bash-4.3.30-upstream_fixes-3.patch is new...

Marcel
> 
>> 
>> Signed-off-by: Marcel Lorenz <marcel.lorenz@ipfire.org>
>> ---
>>  config/rootfiles/common/bash                   |  12 +
>>  lfs/bash                                       |  20 +-
>>  src/patches/bash-3.2-ssh_source_bash.patch     |  12 -
>>  src/patches/bash-4.0-paths-1.patch             |  11 -
>>  src/patches/bash-4.0-profile-1.patch           |  12 -
>>  src/patches/bash-4.3.30-upstream_fixes-3.patch | 488
>> +++++++++++++++++++++++++
>>  6 files changed, 505 insertions(+), 50 deletions(-)
>>  delete mode 100644 src/patches/bash-3.2-ssh_source_bash.patch
>>  delete mode 100644 src/patches/bash-4.0-paths-1.patch
>>  delete mode 100644 src/patches/bash-4.0-profile-1.patch
>>  create mode 100644 src/patches/bash-4.3.30-upstream_fixes-3.patch
>> 
>> diff --git a/config/rootfiles/common/bash 
>> b/config/rootfiles/common/bash
>> index 84f587f..743a71a 100644
>> --- a/config/rootfiles/common/bash
>> +++ b/config/rootfiles/common/bash
>> @@ -57,3 +57,15 @@ bin/bash
>>  #usr/share/locale/zh_TW/LC_MESSAGES/bash.mo
>>  #usr/share/man/man1/bash.1
>>  #usr/share/man/man1/bashbug.1
>> +#usr/share/doc/bash-4.3.30
>> +#usr/share/doc/bash-4.3.30/CHANGES
>> +#usr/share/doc/bash-4.3.30/COMPAT
>> +#usr/share/doc/bash-4.3.30/FAQ
>> +#usr/share/doc/bash-4.3.30/INTRO
>> +#usr/share/doc/bash-4.3.30/NEWS
>> +#usr/share/doc/bash-4.3.30/POSIX
>> +#usr/share/doc/bash-4.3.30/RBASH
>> +#usr/share/doc/bash-4.3.30/README
>> +#usr/share/doc/bash-4.3.30/bash.html
>> +#usr/share/doc/bash-4.3.30/bashref.html
>> +
>> diff --git a/lfs/bash b/lfs/bash
>> index c215b5a..416b382 100644
>> --- a/lfs/bash
>> +++ b/lfs/bash
>> @@ -24,7 +24,7 @@
>>  
>>  include Config
>>  
>> -VER        = 4.3
>> +VER        = 4.3.30
>>  
>>  THISAPP    = bash-$(VER)
>>  DL_FILE    = $(THISAPP).tar.gz
>> @@ -43,7 +43,8 @@ else
>>  endif
>>  
>>  CONFIGURE_OPTIONS += \
>> -	--without-bash-malloc
>> +	--without-bash-malloc \
>> +	--docdir=/usr/share/doc/bash-4.3.30
>>  
>>  #############################################################################
>> ##
>>  # Top-level Rules
>> @@ -53,7 +54,7 @@ objects = $(DL_FILE)
>>  
>>  $(DL_FILE)             = $(DL_FROM)/$(DL_FILE)
>>  
>> -$(DL_FILE)_MD5         = 81348932d5da294953e15d4814c74dd1
>> +$(DL_FILE)_MD5         = a27b3ee9be83bd3ba448c0ff52b28447
>>  
>>  install : $(TARGET)
>>  
>> @@ -83,18 +84,7 @@ $(subst %,%_MD5,$(objects)) :
>>  $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
>>  	@$(PREBUILD)
>>  	@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zaxf $(DIR_DL)/$(DL_FILE)
>> -
>> -	sed -e "s/filename, RTLD_LAZY/filename, RTLD_NOW/" \
>> -		-i $(DIR_APP)/builtins/enable.def
>> -
>> -	for i in $$(seq 1 30); do \
>> -		cd $(DIR_APP) && patch -Np0 <
>> $(DIR_SRC)/src/patches/bash/bash43-$$(printf "%03d" "$${i}") || exit 
>> 1; \
>> -	done
>> -
>> -	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash-4.0-paths-
>> 1.patch
>> -	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash-4.0-
>> profile-1.patch
>> -	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash-3.2-
>> ssh_source_bash.patch
>> -
>> +	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash-4.3.30-
>> upstream_fixes-3.patch
>>  	cd $(DIR_APP) && ./configure $(CONFIGURE_OPTIONS)
>>  	cd $(DIR_APP) && make $(MAKETUNING)
>>  	cd $(DIR_APP) && make install
>> diff --git a/src/patches/bash-3.2-ssh_source_bash.patch 
>> b/src/patches/bash-
>> 3.2-ssh_source_bash.patch
>> deleted file mode 100644
>> index 5bd19ce..0000000
>> --- a/src/patches/bash-3.2-ssh_source_bash.patch
>> +++ /dev/null
>> @@ -1,12 +0,0 @@
>> -diff -up bash-4.0/config-top.h.ssh_source_bash bash-4.0/config-top.h
>> ---- bash-4.0/config-top.h.ssh_source_bash	2009-01-21
>> 15:20:06.000000000 +0100
>> -+++ bash-4.0/config-top.h	2009-01-21 15:25:46.000000000 +0100
>> -@@ -90,7 +90,7 @@
>> -    sshd and source the .bashrc if so (like the rshd behavior).  This 
>> checks
>> -    for the presence of SSH_CLIENT or SSH2_CLIENT in the initial 
>> environment,
>> -    which can be fooled under certain not-uncommon circumstances. */
>> --/* #define SSH_SOURCE_BASHRC */
>> -+#define SSH_SOURCE_BASHRC
>> - 
>> - /* Define if you want the case-capitalizing operators (~[~]) and the
>> -    `capcase' variable attribute (declare -c). */
>> diff --git a/src/patches/bash-4.0-paths-1.patch 
>> b/src/patches/bash-4.0-paths-
>> 1.patch
>> deleted file mode 100644
>> index 24ec5cc..0000000
>> --- a/src/patches/bash-4.0-paths-1.patch
>> +++ /dev/null
>> @@ -1,11 +0,0 @@
>> ---- bash-3.0/config-top.h.paths	2003-08-05 15:36:12.000000000 +0100
>> -+++ bash-3.0/config-top.h	2004-07-28 09:36:27.117205637 +0100
>> -@@ -66,7 +66,7 @@
>> -    the Posix.2 confstr () function, or CS_PATH define are not 
>> present. */
>> - #ifndef STANDARD_UTILS_PATH
>> - #define STANDARD_UTILS_PATH \
>> --  "/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc"
>> -+  "/bin:/usr/bin:/usr/sbin:/sbin"
>> - #endif
>> - 
>> - /* Default primary and secondary prompt strings. */
>> diff --git a/src/patches/bash-4.0-profile-1.patch 
>> b/src/patches/bash-4.0-
>> profile-1.patch
>> deleted file mode 100644
>> index ba3344b..0000000
>> --- a/src/patches/bash-4.0-profile-1.patch
>> +++ /dev/null
>> @@ -1,12 +0,0 @@
>> -diff -up bash-3.2/config-top.h.profile bash-3.2/config-top.h
>> ---- bash-3.2/config-top.h.profile	2008-07-17 13:35:39.000000000 +0200
>> -+++ bash-3.2/config-top.h	2008-07-17 13:42:18.000000000 +0200
>> -@@ -26,6 +26,8 @@
>> -    what POSIX.2 specifies. */
>> - #define CONTINUE_AFTER_KILL_ERROR
>> - 
>> -+#define NON_INTERACTIVE_LOGIN_SHELLS
>> -+
>> - /* Define BREAK_COMPLAINS if you want the non-standard, but useful
>> -    error messages about `break' and `continue' out of context. */
>> - #define BREAK_COMPLAINS
>> diff --git a/src/patches/bash-4.3.30-upstream_fixes-3.patch
>> b/src/patches/bash-4.3.30-upstream_fixes-3.patch
>> new file mode 100644
>> index 0000000..459ce26
>> --- /dev/null
>> +++ b/src/patches/bash-4.3.30-upstream_fixes-3.patch
>> @@ -0,0 +1,488 @@
>> +Submitted By:            Armin K. <krejzi at email dot com>
>> +Date:                    2016-02-16
>> +Initial Package Version: 4.3
>> +Upstream Status:         Already in upstream patch repo
>> +Origin:                  Upstream
>> +Description:             This patch contains upstream patch numbers 
>> 031 thru
>> 042
>> +
>> +--- a/arrayfunc.c	2014-10-01 18:57:35.000000000 +0200
>> ++++ b/arrayfunc.c	2015-09-06 22:57:56.328941059 +0200
>> +@@ -404,6 +404,9 @@
>> +       (*var->assign_func) (var, l->word->word, i, 0);
>> +     else
>> +       array_insert (a, i, l->word->word);
>> ++
>> ++  VUNSETATTR (var, att_invisible);	/* no longer invisible */
>> ++
>> +   return var;
>> + }
>> + 
>> +@@ -634,6 +637,10 @@
>> + 
>> +   if (nlist)
>> +     dispose_words (nlist);
>> ++
>> ++  if (var)
>> ++    VUNSETATTR (var, att_invisible);	/* no longer invisible */
>> ++
>> +   return (var);
>> + }
>> + 
>> +--- a/assoc.c	2011-11-05 21:39:05.000000000 +0100
>> ++++ b/assoc.c	2015-09-06 22:57:56.328941059 +0200
>> +@@ -436,6 +436,8 @@
>> + #if 1
>> + 	if (sh_contains_shell_metas (tlist->key))
>> + 	  istr = sh_double_quote (tlist->key);
>> ++	else if (ALL_ELEMENT_SUB (tlist->key[0]) && tlist->key[1] == '\0')
>> ++	  istr = sh_double_quote (tlist->key);
>> + 	else
>> + 	  istr = tlist->key;
>> + #else
>> +--- a/bashline.c	2014-10-01 18:57:30.000000000 +0200
>> ++++ b/bashline.c	2015-09-06 22:58:34.711768943 +0200
>> +@@ -202,6 +202,7 @@
>> + extern int last_command_exit_value;
>> + extern int array_needs_making;
>> + extern int posixly_correct, no_symbolic_links;
>> ++extern int sigalrm_seen;
>> + extern char *current_prompt_string, *ps1_prompt;
>> + extern STRING_INT_ALIST word_token_alist[];
>> + extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
>> +@@ -1467,10 +1468,23 @@
>> + 
>> +       os = start;
>> +       n = 0;
>> ++      was_assignment = 0;
>> +       s = find_cmd_start (os);
>> +       e = find_cmd_end (end);
>> +       do
>> + 	{
>> ++	  /* Don't read past the end of rl_line_buffer */
>> ++	  if (s > rl_end)
>> ++	    {
>> ++	      s1 = s = e1;
>> ++	      break;
>> ++	    }
>> ++	  /* Or past point if point is within an assignment statement */
>> ++	  else if (was_assignment && s > rl_point)
>> ++	    {
>> ++	      s1 = s = e1;
>> ++	      break;
>> ++	    }
>> + 	  /* Skip over assignment statements preceding a command name.  If
>> we
>> + 	     don't find a command name at all, we can perform command name
>> + 	     completion.  If we find a partial command name, we should
>> perform
>> +@@ -4208,8 +4222,9 @@
>> + {
>> +   /* If we're going to longjmp to top_level, make sure we clean up 
>> readline.
>> +      check_signals will call QUIT, which will eventually longjmp to
>> top_level,
>> +-     calling run_interrupt_trap along the way. */
>> +-  if (interrupt_state)
>> ++     calling run_interrupt_trap along the way.  The check for 
>> sigalrm_seen
>> is
>> ++     to clean up the read builtin's state. */
>> ++  if (terminating_signal || interrupt_state || sigalrm_seen)
>> +     rl_cleanup_after_signal ();
>> +   bashline_reset_event_hook ();
>> +   check_signals_and_traps ();	/* XXX */
>> +--- a/builtins/common.h	2014-10-01 18:57:47.000000000 +0200
>> ++++ b/builtins/common.h	2015-09-06 22:57:56.330941103 +0200
>> +@@ -122,6 +122,10 @@
>> + /* Functions from getopts.def */
>> + extern void getopts_reset __P((int));
>> + 
>> ++/* Functions from read.def */
>> ++extern void read_tty_cleanup __P((void));
>> ++extern int read_tty_modified __P((void));
>> ++
>> + /* Functions from set.def */
>> + extern int minus_o_option_value __P((char *));
>> + extern void list_minus_o_opts __P((int, int));
>> +--- a/builtins/read.def	2014-10-01 18:57:38.000000000 +0200
>> ++++ b/builtins/read.def	2015-09-06 22:57:56.335941212 +0200
>> +@@ -140,10 +140,12 @@
>> + procenv_t alrmbuf;
>> + int sigalrm_seen;
>> + 
>> +-static int reading;
>> ++static int reading, tty_modified;
>> + static SigHandler *old_alrm;
>> + static unsigned char delim;
>> + 
>> ++static struct ttsave termsave;
>> ++
>> + /* In all cases, SIGALRM just sets a flag that we check 
>> periodically.  This
>> +    avoids problems with the semi-tricky stuff we do with the xfree 
>> of
>> +    input_string at the top of the unwind-protect list (see below). 
>> */
>> +@@ -188,7 +190,6 @@
>> +   struct stat tsb;
>> +   SHELL_VAR *var;
>> +   TTYSTRUCT ttattrs, ttset;
>> +-  struct ttsave termsave;
>> + #if defined (ARRAY_VARS)
>> +   WORD_LIST *alist;
>> + #endif
>> +@@ -221,7 +222,7 @@
>> +   USE_VAR(ps2);
>> +   USE_VAR(lastsig);
>> + 
>> +-  sigalrm_seen = reading = 0;
>> ++  sigalrm_seen = reading = tty_modified = 0;
>> + 
>> +   i = 0;		/* Index into the string that we are reading. */
>> +   raw = edit = 0;	/* Not reading raw input by default. */
>> +@@ -438,6 +439,8 @@
>> + 	  retval = 128+SIGALRM;
>> + 	  goto assign_vars;
>> + 	}
>> ++      if (interactive_shell == 0)
>> ++	initialize_terminating_signals ();
>> +       old_alrm = set_signal_handler (SIGALRM, sigalrm);
>> +       add_unwind_protect (reset_alarm, (char *)NULL);
>> + #if defined (READLINE)
>> +@@ -482,7 +485,10 @@
>> + 	  i = silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, 
>> &ttset);
>> + 	  if (i < 0)
>> + 	    sh_ttyerror (1);
>> ++	  tty_modified = 1;
>> + 	  add_unwind_protect ((Function *)ttyrestore, (char *)&termsave);
>> ++	  if (interactive_shell == 0)
>> ++	    initialize_terminating_signals ();
>> + 	}
>> +     }
>> +   else if (silent)	/* turn off echo but leave term in canonical mode
>> */
>> +@@ -497,7 +503,10 @@
>> +       if (i < 0)
>> + 	sh_ttyerror (1);
>> + 
>> ++      tty_modified = 1;
>> +       add_unwind_protect ((Function *)ttyrestore, (char 
>> *)&termsave);
>> ++      if (interactive_shell == 0)
>> ++	initialize_terminating_signals ();
>> +     }
>> + 
>> +   /* This *must* be the top unwind-protect on the stack, so the 
>> manipulation
>> +@@ -588,6 +597,8 @@
>> + 	    }
>> + 	  else
>> + 	    lastsig = 0;
>> ++	  if (terminating_signal && tty_modified)
>> ++	    ttyrestore (&termsave);	/* fix terminal before exiting */
>> + 	  CHECK_TERMSIG;
>> + 	  eof = 1;
>> + 	  break;
>> +@@ -978,6 +989,20 @@
>> +      struct ttsave *ttp;
>> + {
>> +   ttsetattr (ttp->fd, ttp->attrs);
>> ++  tty_modified = 0;
>> ++}
>> ++
>> ++void
>> ++read_tty_cleanup ()
>> ++{
>> ++  if (tty_modified)
>> ++    ttyrestore (&termsave);
>> ++}
>> ++
>> ++int
>> ++read_tty_modified ()
>> ++{
>> ++  return (tty_modified);
>> + }
>> + 
>> + #if defined (READLINE)
>> +--- a/builtins/set.def	2013-04-19 13:20:34.000000000 +0200
>> ++++ b/builtins/set.def	2015-09-06 22:57:56.336941234 +0200
>> +@@ -751,9 +751,11 @@
>> +   WORD_LIST *list;
>> + {
>> +   int unset_function, unset_variable, unset_array, opt, nameref, 
>> any_failed;
>> ++  int global_unset_func, global_unset_var;
>> +   char *name;
>> + 
>> +   unset_function = unset_variable = unset_array = nameref = 
>> any_failed = 0;
>> ++  global_unset_func = global_unset_var = 0;
>> + 
>> +   reset_internal_getopt ();
>> +   while ((opt = internal_getopt (list, "fnv")) != -1)
>> +@@ -761,10 +763,10 @@
>> +       switch (opt)
>> + 	{
>> + 	case 'f':
>> +-	  unset_function = 1;
>> ++	  global_unset_func = 1;
>> + 	  break;
>> + 	case 'v':
>> +-	  unset_variable = 1;
>> ++	  global_unset_var = 1;
>> + 	  break;
>> + 	case 'n':
>> + 	  nameref = 1;
>> +@@ -777,7 +779,7 @@
>> + 
>> +   list = loptend;
>> + 
>> +-  if (unset_function && unset_variable)
>> ++  if (global_unset_func && global_unset_var)
>> +     {
>> +       builtin_error (_("cannot simultaneously unset a function and a
>> variable"));
>> +       return (EXECUTION_FAILURE);
>> +@@ -795,6 +797,9 @@
>> + 
>> +       name = list->word->word;
>> + 
>> ++      unset_function = global_unset_func;
>> ++      unset_variable = global_unset_var;
>> ++
>> + #if defined (ARRAY_VARS)
>> +       unset_array = 0;
>> +       if (!unset_function && valid_array_reference (name))
>> +--- a/jobs.c	2014-10-01 18:57:26.000000000 +0200
>> ++++ b/jobs.c	2015-09-06 22:57:56.340941321 +0200
>> +@@ -3339,7 +3339,9 @@
>> +       if (posixly_correct && this_shell_builtin && 
>> this_shell_builtin ==
>> wait_builtin)
>> + 	{
>> + 	  interrupt_immediately = 0;
>> +-	  trap_handler (SIGCHLD);	/* set pending_traps[SIGCHLD] */
>> ++	  /* This was trap_handler (SIGCHLD) but that can lose traps if
>> ++	     children_exited > 1 */
>> ++	  queue_sigchld_trap (children_exited);
>> + 	  wait_signal_received = SIGCHLD;
>> + 	  /* If we're in a signal handler, let CHECK_WAIT_INTR pick it up;
>> + 	     run_pending_traps will call run_sigchld_trap later  */
>> +--- a/lib/readline/complete.c	2013-10-14 15:27:10.000000000 +0200
>> ++++ b/lib/readline/complete.c	2015-09-06 22:58:34.712768964 +0200
>> +@@ -689,6 +689,8 @@
>> + 
>> +   if (temp == 0 || *temp == '\0')
>> +     return (pathname);
>> ++  else if (temp[1] == 0 && temp == pathname)
>> ++    return (pathname);
>> +   /* If the basename is NULL, we might have a pathname like 
>> '/usr/src/'.
>> +      Look for a previous slash and, if one is found, return the 
>> portion
>> +      following that slash.  If there's no previous slash, just 
>> return the
>> +--- a/lib/sh/unicode.c	2014-01-30 22:47:19.000000000 +0100
>> ++++ b/lib/sh/unicode.c	2015-09-06 22:57:56.341941343 +0200
>> +@@ -78,13 +78,15 @@
>> +   s = strrchr (locale, '.');
>> +   if (s)
>> +     {
>> +-      strcpy (charsetbuf, s+1);
>> ++      strncpy (charsetbuf, s+1, sizeof (charsetbuf) - 1);
>> ++      charsetbuf[sizeof (charsetbuf) - 1] = '\0';
>> +       t = strchr (charsetbuf, '@');
>> +       if (t)
>> + 	*t = 0;
>> +       return charsetbuf;
>> +     }
>> +-  strcpy (charsetbuf, locale);
>> ++  strncpy (charsetbuf, locale, sizeof (charsetbuf) - 1);
>> ++  charsetbuf[sizeof (charsetbuf) - 1] = '\0';
>> +   return charsetbuf;
>> + }
>> + #endif
>> +--- a/parse.y	2014-10-05 19:52:50.000000000 +0200
>> ++++ b/parse.y	2015-09-06 22:58:35.245780313 +0200
>> +@@ -2818,11 +2818,16 @@
>> +     case AND_AND:
>> +     case OR_OR:
>> +     case '&':
>> ++    case WHILE:
>> +     case DO:
>> ++    case UNTIL:
>> ++    case IF:
>> +     case THEN:
>> ++    case ELIF:
>> +     case ELSE:
>> +     case '{':		/* } */
>> +-    case '(':		/* ) */
>> ++    case '(':		/* )( */
>> ++    case ')':		/* only valid in case statement */
>> +     case BANG:		/* ! time pipeline */
>> +     case TIME:		/* time time pipeline */
>> +     case TIMEOPT:	/* time -p time pipeline */
>> +@@ -3703,6 +3708,8 @@
>> + /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", 
>> line_number, ch,
>> __LINE__);*/
>> + 	      tflags |= LEX_INWORD;
>> + 	      lex_wlen = 0;
>> ++	      if (tflags & LEX_RESWDOK)
>> ++		lex_rwlen = 0;
>> + 	    }
>> + 	}
>> + 
>> +--- a/patchlevel.h	2014-10-05 19:52:50.000000000 +0200
>> ++++ b/patchlevel.h	2015-09-06 22:58:35.248780377 +0200
>> +@@ -25,6 +25,6 @@
>> +    regexp `^#define[ 	]*PATCHLEVEL', since that's what
>> support/mkversion.sh
>> +    looks for to find the patch level (for the sccs version string). 
>> */
>> + 
>> +-#define PATCHLEVEL 30
>> ++#define PATCHLEVEL 42
>> + 
>> + #endif /* _PATCHLEVEL_H_ */
>> +--- a/shell.c	2014-01-14 14:04:32.000000000 +0100
>> ++++ b/shell.c	2015-09-06 22:57:56.343941387 +0200
>> +@@ -73,6 +73,7 @@
>> + #endif
>> + 
>> + #if defined (READLINE)
>> ++#  include <readline/readline.h>
>> + #  include "bashline.h"
>> + #endif
>> + 
>> +@@ -909,6 +910,14 @@
>> +   fflush (stdout);		/* XXX */
>> +   fflush (stderr);
>> + 
>> ++  /* Clean up the terminal if we are in a state where it's been 
>> modified. */
>> ++#if defined (READLINE)
>> ++  if (RL_ISSTATE (RL_STATE_TERMPREPPED) && rl_deprep_term_function)
>> ++    (*rl_deprep_term_function) ();
>> ++#endif
>> ++  if (read_tty_modified ())
>> ++    read_tty_cleanup ();
>> ++
>> +   /* Do trap[0] if defined.  Allow it to override the exit status
>> +      passed to us. */
>> +   if (signal_is_trapped (0))
>> +--- a/sig.c	2014-01-10 21:06:06.000000000 +0100
>> ++++ b/sig.c	2015-09-06 22:57:56.344941408 +0200
>> +@@ -532,8 +532,10 @@
>> + #if defined (READLINE)
>> +   /* Set the event hook so readline will call it after the signal 
>> handlers
>> +      finish executing, so if this interrupted character input we can 
>> get
>> +-     quick response. */
>> +-  if (interactive_shell && interactive && no_line_editing == 0)
>> ++     quick response.  If readline is active or has modified the 
>> terminal we
>> ++     need to set this no matter what the signal is, though the check 
>> for
>> ++     RL_STATE_TERMPREPPED is possibly redundant. */
>> ++  if (RL_ISSTATE (RL_STATE_SIGHANDLER) || RL_ISSTATE 
>> (RL_STATE_TERMPREPPED))
>> +     bashline_set_event_hook ();
>> + #endif
>> + 
>> +--- a/subst.c	2014-10-01 18:57:47.000000000 +0200
>> ++++ b/subst.c	2015-09-06 22:58:34.177757570 +0200
>> +@@ -5782,7 +5782,7 @@
>> +       /* XXX - does this leak if name[@] or name[*]? */
>> +       if (pflags & PF_ASSIGNRHS)
>> +         {
>> +-          temp = array_variable_name (name, &tt, (int *)0);
>> ++          var = array_variable_part (name, &tt, (int *)0);
>> +           if (ALL_ELEMENT_SUB (tt[0]) && tt[1] == ']')
>> + 	    temp = array_value (name, quoted|Q_DOUBLE_QUOTES, 0, &atype,
>> &ind);
>> + 	  else
>> +--- a/subst.h	2014-10-01 18:57:43.000000000 +0200
>> ++++ b/subst.h	2015-09-06 22:57:56.344941408 +0200
>> +@@ -47,6 +47,7 @@
>> + #define ASS_MKASSOC	0x0004
>> + #define ASS_MKGLOBAL	0x0008	/* force global assignment */
>> + #define ASS_NAMEREF	0x0010	/* assigning to nameref variable */
>> ++#define ASS_FROMREF	0x0020	/* assigning from value of nameref
>> variable */
>> + 
>> + /* Flags for the string extraction functions. */
>> + #define SX_NOALLOC	0x0001	/* just skip; don't return substring
>> */
>> +--- a/variables.c	2014-10-01 18:57:51.000000000 +0200
>> ++++ b/variables.c	2015-09-06 22:57:56.345941430 +0200
>> +@@ -2516,10 +2516,27 @@
>> +      HASH_TABLE *table;
>> +      int hflags, aflags;
>> + {
>> +-  char *newval;
>> ++  char *newname, *newval;
>> +   SHELL_VAR *entry;
>> ++#if defined (ARRAY_VARS)
>> ++  arrayind_t ind;
>> ++  char *subp;
>> ++  int sublen;
>> ++#endif
>> + 
>> ++  newname = 0;
>> ++#if defined (ARRAY_VARS)
>> ++  if ((aflags & ASS_FROMREF) && (hflags & HASH_NOSRCH) == 0 &&
>> valid_array_reference (name))
>> ++    {
>> ++      newname = array_variable_name (name, &subp, &sublen);
>> ++      if (newname == 0)
>> ++	return (SHELL_VAR *)NULL;	/* XXX */
>> ++      entry = hash_lookup (newname, table);
>> ++    }
>> ++  else
>> ++#endif
>> +   entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup 
>> (name,
>> table);
>> ++
>> +   /* Follow the nameref chain here if this is the global variables 
>> table */
>> +   if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && 
>> table ==
>> global_variables->table)
>> +     {
>> +@@ -2550,6 +2567,16 @@
>> +       var_setvalue (entry, make_variable_value (entry, value, 0));
>> +       }
>> +     }
>> ++#if defined (ARRAY_VARS)
>> ++  else if (entry == 0 && newname)
>> ++    {
>> ++      entry = make_new_array_variable (newname);	/* indexed array by
>> default */
>> ++      if (entry == 0)
>> ++	return entry;
>> ++      ind = array_expand_index (name, subp, sublen);
>> ++      bind_array_element (entry, ind, value, aflags);
>> ++    }
>> ++#endif
>> +   else if (entry == 0)
>> +     {
>> +       entry = make_new_variable (name, table);
>> +@@ -2670,7 +2697,8 @@
>> + 			 normal. */
>> + 		      if (nameref_cell (nv) == 0)
>> + 			return (bind_variable_internal (nv->name, value,
>> nvc->table, 0, flags));
>> +-		      return (bind_variable_internal (nameref_cell (nv),
>> value, nvc->table, 0, flags));
>> ++		      /* XXX - bug here with ref=array[index] */
>> ++		      return (bind_variable_internal (nameref_cell (nv),
>> value, nvc->table, 0, flags|ASS_FROMREF));
>> + 		    }
>> + 		  else
>> + 		    v = nv;
>> +@@ -2805,10 +2833,12 @@
>> + #endif
>> +     v = bind_variable (lhs, rhs, 0);
>> + 
>> +-  if (v && isint)
>> +-    VSETATTR (v, att_integer);
>> +-
>> +-  VUNSETATTR (v, att_invisible);
>> ++  if (v)
>> ++    {
>> ++      if (isint)
>> ++	VSETATTR (v, att_integer);
>> ++      VUNSETATTR (v, att_invisible);
>> ++    }
>> + 
>> +   return (v);
>> + }
>> +--- a/y.tab.c	2014-10-05 19:52:50.000000000 +0200
>> ++++ b/y.tab.c	2015-09-06 22:58:35.247780356 +0200
>> +@@ -5130,11 +5130,16 @@
>> +     case AND_AND:
>> +     case OR_OR:
>> +     case '&':
>> ++    case WHILE:
>> +     case DO:
>> ++    case UNTIL:
>> ++    case IF:
>> +     case THEN:
>> ++    case ELIF:
>> +     case ELSE:
>> +     case '{':		/* } */
>> +-    case '(':		/* ) */
>> ++    case '(':		/* )( */
>> ++    case ')':		/* only valid in case statement */
>> +     case BANG:		/* ! time pipeline */
>> +     case TIME:		/* time time pipeline */
>> +     case TIMEOPT:	/* time -p time pipeline */
>> +@@ -6015,6 +6020,8 @@
>> + /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", 
>> line_number, ch,
>> __LINE__);*/
>> + 	      tflags |= LEX_INWORD;
>> + 	      lex_wlen = 0;
>> ++	      if (tflags & LEX_RESWDOK)
>> ++		lex_rwlen = 0;
>> + 	    }
>> + 	}
>> +
  
Michael Tremer June 5, 2016, 8:03 a.m. UTC | #3
On Fri, 2016-06-03 at 19:04 +0200, Marcel Lorenz wrote:
> Am 2016-06-03 17:20, schrieb Michael Tremer:
> > 
> > On Thu, 2016-06-02 at 19:43 +0200, Marcel Lorenz wrote:
> > > 
> > > Old bash patches are removed
> > Why? We need those.
> ok, for what? The bash-4.3.30-upstream_fixes-3.patch is new...

Well, have a look at the patches... Loading bashrc for sessions over SSH and
such things...

I didn't see that that was replaced by the upstream fixes patch.

-Michael

> 
> Marcel
> > 
> > 
> > > 
> > > 
> > > Signed-off-by: Marcel Lorenz <marcel.lorenz@ipfire.org>
> > > ---
> > >  config/rootfiles/common/bash                   |  12 +
> > >  lfs/bash                                       |  20 +-
> > >  src/patches/bash-3.2-ssh_source_bash.patch     |  12 -
> > >  src/patches/bash-4.0-paths-1.patch             |  11 -
> > >  src/patches/bash-4.0-profile-1.patch           |  12 -
> > >  src/patches/bash-4.3.30-upstream_fixes-3.patch | 488
> > > +++++++++++++++++++++++++
> > >  6 files changed, 505 insertions(+), 50 deletions(-)
> > >  delete mode 100644 src/patches/bash-3.2-ssh_source_bash.patch
> > >  delete mode 100644 src/patches/bash-4.0-paths-1.patch
> > >  delete mode 100644 src/patches/bash-4.0-profile-1.patch
> > >  create mode 100644 src/patches/bash-4.3.30-upstream_fixes-3.patch
> > > 
> > > diff --git a/config/rootfiles/common/bash 
> > > b/config/rootfiles/common/bash
> > > index 84f587f..743a71a 100644
> > > --- a/config/rootfiles/common/bash
> > > +++ b/config/rootfiles/common/bash
> > > @@ -57,3 +57,15 @@ bin/bash
> > >  #usr/share/locale/zh_TW/LC_MESSAGES/bash.mo
> > >  #usr/share/man/man1/bash.1
> > >  #usr/share/man/man1/bashbug.1
> > > +#usr/share/doc/bash-4.3.30
> > > +#usr/share/doc/bash-4.3.30/CHANGES
> > > +#usr/share/doc/bash-4.3.30/COMPAT
> > > +#usr/share/doc/bash-4.3.30/FAQ
> > > +#usr/share/doc/bash-4.3.30/INTRO
> > > +#usr/share/doc/bash-4.3.30/NEWS
> > > +#usr/share/doc/bash-4.3.30/POSIX
> > > +#usr/share/doc/bash-4.3.30/RBASH
> > > +#usr/share/doc/bash-4.3.30/README
> > > +#usr/share/doc/bash-4.3.30/bash.html
> > > +#usr/share/doc/bash-4.3.30/bashref.html
> > > +
> > > diff --git a/lfs/bash b/lfs/bash
> > > index c215b5a..416b382 100644
> > > --- a/lfs/bash
> > > +++ b/lfs/bash
> > > @@ -24,7 +24,7 @@
> > >  
> > >  include Config
> > >  
> > > -VER        = 4.3
> > > +VER        = 4.3.30
> > >  
> > >  THISAPP    = bash-$(VER)
> > >  DL_FILE    = $(THISAPP).tar.gz
> > > @@ -43,7 +43,8 @@ else
> > >  endif
> > >  
> > >  CONFIGURE_OPTIONS += \
> > > -	--without-bash-malloc
> > > +	--without-bash-malloc \
> > > +	--docdir=/usr/share/doc/bash-4.3.30
> > >  
> > >  #########################################################################
> > > ####
> > > ##
> > >  # Top-level Rules
> > > @@ -53,7 +54,7 @@ objects = $(DL_FILE)
> > >  
> > >  $(DL_FILE)             = $(DL_FROM)/$(DL_FILE)
> > >  
> > > -$(DL_FILE)_MD5         = 81348932d5da294953e15d4814c74dd1
> > > +$(DL_FILE)_MD5         = a27b3ee9be83bd3ba448c0ff52b28447
> > >  
> > >  install : $(TARGET)
> > >  
> > > @@ -83,18 +84,7 @@ $(subst %,%_MD5,$(objects)) :
> > >  $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
> > >  	@$(PREBUILD)
> > >  	@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zaxf
> > > $(DIR_DL)/$(DL_FILE)
> > > -
> > > -	sed -e "s/filename, RTLD_LAZY/filename, RTLD_NOW/" \
> > > -		-i $(DIR_APP)/builtins/enable.def
> > > -
> > > -	for i in $$(seq 1 30); do \
> > > -		cd $(DIR_APP) && patch -Np0 <
> > > $(DIR_SRC)/src/patches/bash/bash43-$$(printf "%03d" "$${i}") || exit 
> > > 1; \
> > > -	done
> > > -
> > > -	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash-4.0-
> > > paths-
> > > 1.patch
> > > -	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash-4.0-
> > > profile-1.patch
> > > -	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash-3.2-
> > > ssh_source_bash.patch
> > > -
> > > +	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash-4.3.30-
> > > upstream_fixes-3.patch
> > >  	cd $(DIR_APP) && ./configure $(CONFIGURE_OPTIONS)
> > >  	cd $(DIR_APP) && make $(MAKETUNING)
> > >  	cd $(DIR_APP) && make install
> > > diff --git a/src/patches/bash-3.2-ssh_source_bash.patch 
> > > b/src/patches/bash-
> > > 3.2-ssh_source_bash.patch
> > > deleted file mode 100644
> > > index 5bd19ce..0000000
> > > --- a/src/patches/bash-3.2-ssh_source_bash.patch
> > > +++ /dev/null
> > > @@ -1,12 +0,0 @@
> > > -diff -up bash-4.0/config-top.h.ssh_source_bash bash-4.0/config-top.h
> > > ---- bash-4.0/config-top.h.ssh_source_bash	2009-01-21
> > > 15:20:06.000000000 +0100
> > > -+++ bash-4.0/config-top.h	2009-01-21 15:25:46.000000000 +0100
> > > -@@ -90,7 +90,7 @@
> > > -    sshd and source the .bashrc if so (like the rshd behavior).  This 
> > > checks
> > > -    for the presence of SSH_CLIENT or SSH2_CLIENT in the initial 
> > > environment,
> > > -    which can be fooled under certain not-uncommon circumstances. */
> > > --/* #define SSH_SOURCE_BASHRC */
> > > -+#define SSH_SOURCE_BASHRC
> > > - 
> > > - /* Define if you want the case-capitalizing operators (~[~]) and the
> > > -    `capcase' variable attribute (declare -c). */
> > > diff --git a/src/patches/bash-4.0-paths-1.patch 
> > > b/src/patches/bash-4.0-paths-
> > > 1.patch
> > > deleted file mode 100644
> > > index 24ec5cc..0000000
> > > --- a/src/patches/bash-4.0-paths-1.patch
> > > +++ /dev/null
> > > @@ -1,11 +0,0 @@
> > > ---- bash-3.0/config-top.h.paths	2003-08-05 15:36:12.000000000
> > > +0100
> > > -+++ bash-3.0/config-top.h	2004-07-28 09:36:27.117205637 +0100
> > > -@@ -66,7 +66,7 @@
> > > -    the Posix.2 confstr () function, or CS_PATH define are not 
> > > present. */
> > > - #ifndef STANDARD_UTILS_PATH
> > > - #define STANDARD_UTILS_PATH \
> > > --  "/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc"
> > > -+  "/bin:/usr/bin:/usr/sbin:/sbin"
> > > - #endif
> > > - 
> > > - /* Default primary and secondary prompt strings. */
> > > diff --git a/src/patches/bash-4.0-profile-1.patch 
> > > b/src/patches/bash-4.0-
> > > profile-1.patch
> > > deleted file mode 100644
> > > index ba3344b..0000000
> > > --- a/src/patches/bash-4.0-profile-1.patch
> > > +++ /dev/null
> > > @@ -1,12 +0,0 @@
> > > -diff -up bash-3.2/config-top.h.profile bash-3.2/config-top.h
> > > ---- bash-3.2/config-top.h.profile	2008-07-17 13:35:39.000000000
> > > +0200
> > > -+++ bash-3.2/config-top.h	2008-07-17 13:42:18.000000000 +0200
> > > -@@ -26,6 +26,8 @@
> > > -    what POSIX.2 specifies. */
> > > - #define CONTINUE_AFTER_KILL_ERROR
> > > - 
> > > -+#define NON_INTERACTIVE_LOGIN_SHELLS
> > > -+
> > > - /* Define BREAK_COMPLAINS if you want the non-standard, but useful
> > > -    error messages about `break' and `continue' out of context. */
> > > - #define BREAK_COMPLAINS
> > > diff --git a/src/patches/bash-4.3.30-upstream_fixes-3.patch
> > > b/src/patches/bash-4.3.30-upstream_fixes-3.patch
> > > new file mode 100644
> > > index 0000000..459ce26
> > > --- /dev/null
> > > +++ b/src/patches/bash-4.3.30-upstream_fixes-3.patch
> > > @@ -0,0 +1,488 @@
> > > +Submitted By:            Armin K. <krejzi at email dot com>
> > > +Date:                    2016-02-16
> > > +Initial Package Version: 4.3
> > > +Upstream Status:         Already in upstream patch repo
> > > +Origin:                  Upstream
> > > +Description:             This patch contains upstream patch numbers 
> > > 031 thru
> > > 042
> > > +
> > > +--- a/arrayfunc.c	2014-10-01 18:57:35.000000000 +0200
> > > ++++ b/arrayfunc.c	2015-09-06 22:57:56.328941059 +0200
> > > +@@ -404,6 +404,9 @@
> > > +       (*var->assign_func) (var, l->word->word, i, 0);
> > > +     else
> > > +       array_insert (a, i, l->word->word);
> > > ++
> > > ++  VUNSETATTR (var, att_invisible);	/* no longer invisible */
> > > ++
> > > +   return var;
> > > + }
> > > + 
> > > +@@ -634,6 +637,10 @@
> > > + 
> > > +   if (nlist)
> > > +     dispose_words (nlist);
> > > ++
> > > ++  if (var)
> > > ++    VUNSETATTR (var, att_invisible);	/* no longer invisible */
> > > ++
> > > +   return (var);
> > > + }
> > > + 
> > > +--- a/assoc.c	2011-11-05 21:39:05.000000000 +0100
> > > ++++ b/assoc.c	2015-09-06 22:57:56.328941059 +0200
> > > +@@ -436,6 +436,8 @@
> > > + #if 1
> > > + 	if (sh_contains_shell_metas (tlist->key))
> > > + 	  istr = sh_double_quote (tlist->key);
> > > ++	else if (ALL_ELEMENT_SUB (tlist->key[0]) && tlist->key[1] ==
> > > '\0')
> > > ++	  istr = sh_double_quote (tlist->key);
> > > + 	else
> > > + 	  istr = tlist->key;
> > > + #else
> > > +--- a/bashline.c	2014-10-01 18:57:30.000000000 +0200
> > > ++++ b/bashline.c	2015-09-06 22:58:34.711768943 +0200
> > > +@@ -202,6 +202,7 @@
> > > + extern int last_command_exit_value;
> > > + extern int array_needs_making;
> > > + extern int posixly_correct, no_symbolic_links;
> > > ++extern int sigalrm_seen;
> > > + extern char *current_prompt_string, *ps1_prompt;
> > > + extern STRING_INT_ALIST word_token_alist[];
> > > + extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
> > > +@@ -1467,10 +1468,23 @@
> > > + 
> > > +       os = start;
> > > +       n = 0;
> > > ++      was_assignment = 0;
> > > +       s = find_cmd_start (os);
> > > +       e = find_cmd_end (end);
> > > +       do
> > > + 	{
> > > ++	  /* Don't read past the end of rl_line_buffer */
> > > ++	  if (s > rl_end)
> > > ++	    {
> > > ++	      s1 = s = e1;
> > > ++	      break;
> > > ++	    }
> > > ++	  /* Or past point if point is within an assignment statement */
> > > ++	  else if (was_assignment && s > rl_point)
> > > ++	    {
> > > ++	      s1 = s = e1;
> > > ++	      break;
> > > ++	    }
> > > + 	  /* Skip over assignment statements preceding a command
> > > name.  If
> > > we
> > > + 	     don't find a command name at all, we can perform command
> > > name
> > > + 	     completion.  If we find a partial command name, we should
> > > perform
> > > +@@ -4208,8 +4222,9 @@
> > > + {
> > > +   /* If we're going to longjmp to top_level, make sure we clean up 
> > > readline.
> > > +      check_signals will call QUIT, which will eventually longjmp to
> > > top_level,
> > > +-     calling run_interrupt_trap along the way. */
> > > +-  if (interrupt_state)
> > > ++     calling run_interrupt_trap along the way.  The check for 
> > > sigalrm_seen
> > > is
> > > ++     to clean up the read builtin's state. */
> > > ++  if (terminating_signal || interrupt_state || sigalrm_seen)
> > > +     rl_cleanup_after_signal ();
> > > +   bashline_reset_event_hook ();
> > > +   check_signals_and_traps ();	/* XXX */
> > > +--- a/builtins/common.h	2014-10-01 18:57:47.000000000 +0200
> > > ++++ b/builtins/common.h	2015-09-06 22:57:56.330941103 +0200
> > > +@@ -122,6 +122,10 @@
> > > + /* Functions from getopts.def */
> > > + extern void getopts_reset __P((int));
> > > + 
> > > ++/* Functions from read.def */
> > > ++extern void read_tty_cleanup __P((void));
> > > ++extern int read_tty_modified __P((void));
> > > ++
> > > + /* Functions from set.def */
> > > + extern int minus_o_option_value __P((char *));
> > > + extern void list_minus_o_opts __P((int, int));
> > > +--- a/builtins/read.def	2014-10-01 18:57:38.000000000 +0200
> > > ++++ b/builtins/read.def	2015-09-06 22:57:56.335941212 +0200
> > > +@@ -140,10 +140,12 @@
> > > + procenv_t alrmbuf;
> > > + int sigalrm_seen;
> > > + 
> > > +-static int reading;
> > > ++static int reading, tty_modified;
> > > + static SigHandler *old_alrm;
> > > + static unsigned char delim;
> > > + 
> > > ++static struct ttsave termsave;
> > > ++
> > > + /* In all cases, SIGALRM just sets a flag that we check 
> > > periodically.  This
> > > +    avoids problems with the semi-tricky stuff we do with the xfree 
> > > of
> > > +    input_string at the top of the unwind-protect list (see below). 
> > > */
> > > +@@ -188,7 +190,6 @@
> > > +   struct stat tsb;
> > > +   SHELL_VAR *var;
> > > +   TTYSTRUCT ttattrs, ttset;
> > > +-  struct ttsave termsave;
> > > + #if defined (ARRAY_VARS)
> > > +   WORD_LIST *alist;
> > > + #endif
> > > +@@ -221,7 +222,7 @@
> > > +   USE_VAR(ps2);
> > > +   USE_VAR(lastsig);
> > > + 
> > > +-  sigalrm_seen = reading = 0;
> > > ++  sigalrm_seen = reading = tty_modified = 0;
> > > + 
> > > +   i = 0;		/* Index into the string that we are reading. */
> > > +   raw = edit = 0;	/* Not reading raw input by default. */
> > > +@@ -438,6 +439,8 @@
> > > + 	  retval = 128+SIGALRM;
> > > + 	  goto assign_vars;
> > > + 	}
> > > ++      if (interactive_shell == 0)
> > > ++	initialize_terminating_signals ();
> > > +       old_alrm = set_signal_handler (SIGALRM, sigalrm);
> > > +       add_unwind_protect (reset_alarm, (char *)NULL);
> > > + #if defined (READLINE)
> > > +@@ -482,7 +485,10 @@
> > > + 	  i = silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, 
> > > &ttset);
> > > + 	  if (i < 0)
> > > + 	    sh_ttyerror (1);
> > > ++	  tty_modified = 1;
> > > + 	  add_unwind_protect ((Function *)ttyrestore, (char
> > > *)&termsave);
> > > ++	  if (interactive_shell == 0)
> > > ++	    initialize_terminating_signals ();
> > > + 	}
> > > +     }
> > > +   else if (silent)	/* turn off echo but leave term in canonical
> > > mode
> > > */
> > > +@@ -497,7 +503,10 @@
> > > +       if (i < 0)
> > > + 	sh_ttyerror (1);
> > > + 
> > > ++      tty_modified = 1;
> > > +       add_unwind_protect ((Function *)ttyrestore, (char 
> > > *)&termsave);
> > > ++      if (interactive_shell == 0)
> > > ++	initialize_terminating_signals ();
> > > +     }
> > > + 
> > > +   /* This *must* be the top unwind-protect on the stack, so the 
> > > manipulation
> > > +@@ -588,6 +597,8 @@
> > > + 	    }
> > > + 	  else
> > > + 	    lastsig = 0;
> > > ++	  if (terminating_signal && tty_modified)
> > > ++	    ttyrestore (&termsave);	/* fix terminal before
> > > exiting */
> > > + 	  CHECK_TERMSIG;
> > > + 	  eof = 1;
> > > + 	  break;
> > > +@@ -978,6 +989,20 @@
> > > +      struct ttsave *ttp;
> > > + {
> > > +   ttsetattr (ttp->fd, ttp->attrs);
> > > ++  tty_modified = 0;
> > > ++}
> > > ++
> > > ++void
> > > ++read_tty_cleanup ()
> > > ++{
> > > ++  if (tty_modified)
> > > ++    ttyrestore (&termsave);
> > > ++}
> > > ++
> > > ++int
> > > ++read_tty_modified ()
> > > ++{
> > > ++  return (tty_modified);
> > > + }
> > > + 
> > > + #if defined (READLINE)
> > > +--- a/builtins/set.def	2013-04-19 13:20:34.000000000 +0200
> > > ++++ b/builtins/set.def	2015-09-06 22:57:56.336941234 +0200
> > > +@@ -751,9 +751,11 @@
> > > +   WORD_LIST *list;
> > > + {
> > > +   int unset_function, unset_variable, unset_array, opt, nameref, 
> > > any_failed;
> > > ++  int global_unset_func, global_unset_var;
> > > +   char *name;
> > > + 
> > > +   unset_function = unset_variable = unset_array = nameref = 
> > > any_failed = 0;
> > > ++  global_unset_func = global_unset_var = 0;
> > > + 
> > > +   reset_internal_getopt ();
> > > +   while ((opt = internal_getopt (list, "fnv")) != -1)
> > > +@@ -761,10 +763,10 @@
> > > +       switch (opt)
> > > + 	{
> > > + 	case 'f':
> > > +-	  unset_function = 1;
> > > ++	  global_unset_func = 1;
> > > + 	  break;
> > > + 	case 'v':
> > > +-	  unset_variable = 1;
> > > ++	  global_unset_var = 1;
> > > + 	  break;
> > > + 	case 'n':
> > > + 	  nameref = 1;
> > > +@@ -777,7 +779,7 @@
> > > + 
> > > +   list = loptend;
> > > + 
> > > +-  if (unset_function && unset_variable)
> > > ++  if (global_unset_func && global_unset_var)
> > > +     {
> > > +       builtin_error (_("cannot simultaneously unset a function and a
> > > variable"));
> > > +       return (EXECUTION_FAILURE);
> > > +@@ -795,6 +797,9 @@
> > > + 
> > > +       name = list->word->word;
> > > + 
> > > ++      unset_function = global_unset_func;
> > > ++      unset_variable = global_unset_var;
> > > ++
> > > + #if defined (ARRAY_VARS)
> > > +       unset_array = 0;
> > > +       if (!unset_function && valid_array_reference (name))
> > > +--- a/jobs.c	2014-10-01 18:57:26.000000000 +0200
> > > ++++ b/jobs.c	2015-09-06 22:57:56.340941321 +0200
> > > +@@ -3339,7 +3339,9 @@
> > > +       if (posixly_correct && this_shell_builtin && 
> > > this_shell_builtin ==
> > > wait_builtin)
> > > + 	{
> > > + 	  interrupt_immediately = 0;
> > > +-	  trap_handler (SIGCHLD);	/* set pending_traps[SIGCHLD]
> > > */
> > > ++	  /* This was trap_handler (SIGCHLD) but that can lose traps if
> > > ++	     children_exited > 1 */
> > > ++	  queue_sigchld_trap (children_exited);
> > > + 	  wait_signal_received = SIGCHLD;
> > > + 	  /* If we're in a signal handler, let CHECK_WAIT_INTR pick it
> > > up;
> > > + 	     run_pending_traps will call run_sigchld_trap later  */
> > > +--- a/lib/readline/complete.c	2013-10-14 15:27:10.000000000 +0200
> > > ++++ b/lib/readline/complete.c	2015-09-06 22:58:34.712768964 +0200
> > > +@@ -689,6 +689,8 @@
> > > + 
> > > +   if (temp == 0 || *temp == '\0')
> > > +     return (pathname);
> > > ++  else if (temp[1] == 0 && temp == pathname)
> > > ++    return (pathname);
> > > +   /* If the basename is NULL, we might have a pathname like 
> > > '/usr/src/'.
> > > +      Look for a previous slash and, if one is found, return the 
> > > portion
> > > +      following that slash.  If there's no previous slash, just 
> > > return the
> > > +--- a/lib/sh/unicode.c	2014-01-30 22:47:19.000000000 +0100
> > > ++++ b/lib/sh/unicode.c	2015-09-06 22:57:56.341941343 +0200
> > > +@@ -78,13 +78,15 @@
> > > +   s = strrchr (locale, '.');
> > > +   if (s)
> > > +     {
> > > +-      strcpy (charsetbuf, s+1);
> > > ++      strncpy (charsetbuf, s+1, sizeof (charsetbuf) - 1);
> > > ++      charsetbuf[sizeof (charsetbuf) - 1] = '\0';
> > > +       t = strchr (charsetbuf, '@');
> > > +       if (t)
> > > + 	*t = 0;
> > > +       return charsetbuf;
> > > +     }
> > > +-  strcpy (charsetbuf, locale);
> > > ++  strncpy (charsetbuf, locale, sizeof (charsetbuf) - 1);
> > > ++  charsetbuf[sizeof (charsetbuf) - 1] = '\0';
> > > +   return charsetbuf;
> > > + }
> > > + #endif
> > > +--- a/parse.y	2014-10-05 19:52:50.000000000 +0200
> > > ++++ b/parse.y	2015-09-06 22:58:35.245780313 +0200
> > > +@@ -2818,11 +2818,16 @@
> > > +     case AND_AND:
> > > +     case OR_OR:
> > > +     case '&':
> > > ++    case WHILE:
> > > +     case DO:
> > > ++    case UNTIL:
> > > ++    case IF:
> > > +     case THEN:
> > > ++    case ELIF:
> > > +     case ELSE:
> > > +     case '{':		/* } */
> > > +-    case '(':		/* ) */
> > > ++    case '(':		/* )( */
> > > ++    case ')':		/* only valid in case statement */
> > > +     case BANG:		/* ! time pipeline */
> > > +     case TIME:		/* time time pipeline */
> > > +     case TIMEOPT:	/* time -p time pipeline */
> > > +@@ -3703,6 +3708,8 @@
> > > + /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", 
> > > line_number, ch,
> > > __LINE__);*/
> > > + 	      tflags |= LEX_INWORD;
> > > + 	      lex_wlen = 0;
> > > ++	      if (tflags & LEX_RESWDOK)
> > > ++		lex_rwlen = 0;
> > > + 	    }
> > > + 	}
> > > + 
> > > +--- a/patchlevel.h	2014-10-05 19:52:50.000000000 +0200
> > > ++++ b/patchlevel.h	2015-09-06 22:58:35.248780377 +0200
> > > +@@ -25,6 +25,6 @@
> > > +    regexp `^#define[ 	]*PATCHLEVEL', since that's what
> > > support/mkversion.sh
> > > +    looks for to find the patch level (for the sccs version string). 
> > > */
> > > + 
> > > +-#define PATCHLEVEL 30
> > > ++#define PATCHLEVEL 42
> > > + 
> > > + #endif /* _PATCHLEVEL_H_ */
> > > +--- a/shell.c	2014-01-14 14:04:32.000000000 +0100
> > > ++++ b/shell.c	2015-09-06 22:57:56.343941387 +0200
> > > +@@ -73,6 +73,7 @@
> > > + #endif
> > > + 
> > > + #if defined (READLINE)
> > > ++#  include <readline/readline.h>
> > > + #  include "bashline.h"
> > > + #endif
> > > + 
> > > +@@ -909,6 +910,14 @@
> > > +   fflush (stdout);		/* XXX */
> > > +   fflush (stderr);
> > > + 
> > > ++  /* Clean up the terminal if we are in a state where it's been 
> > > modified. */
> > > ++#if defined (READLINE)
> > > ++  if (RL_ISSTATE (RL_STATE_TERMPREPPED) && rl_deprep_term_function)
> > > ++    (*rl_deprep_term_function) ();
> > > ++#endif
> > > ++  if (read_tty_modified ())
> > > ++    read_tty_cleanup ();
> > > ++
> > > +   /* Do trap[0] if defined.  Allow it to override the exit status
> > > +      passed to us. */
> > > +   if (signal_is_trapped (0))
> > > +--- a/sig.c	2014-01-10 21:06:06.000000000 +0100
> > > ++++ b/sig.c	2015-09-06 22:57:56.344941408 +0200
> > > +@@ -532,8 +532,10 @@
> > > + #if defined (READLINE)
> > > +   /* Set the event hook so readline will call it after the signal 
> > > handlers
> > > +      finish executing, so if this interrupted character input we can 
> > > get
> > > +-     quick response. */
> > > +-  if (interactive_shell && interactive && no_line_editing == 0)
> > > ++     quick response.  If readline is active or has modified the 
> > > terminal we
> > > ++     need to set this no matter what the signal is, though the check 
> > > for
> > > ++     RL_STATE_TERMPREPPED is possibly redundant. */
> > > ++  if (RL_ISSTATE (RL_STATE_SIGHANDLER) || RL_ISSTATE 
> > > (RL_STATE_TERMPREPPED))
> > > +     bashline_set_event_hook ();
> > > + #endif
> > > + 
> > > +--- a/subst.c	2014-10-01 18:57:47.000000000 +0200
> > > ++++ b/subst.c	2015-09-06 22:58:34.177757570 +0200
> > > +@@ -5782,7 +5782,7 @@
> > > +       /* XXX - does this leak if name[@] or name[*]? */
> > > +       if (pflags & PF_ASSIGNRHS)
> > > +         {
> > > +-          temp = array_variable_name (name, &tt, (int *)0);
> > > ++          var = array_variable_part (name, &tt, (int *)0);
> > > +           if (ALL_ELEMENT_SUB (tt[0]) && tt[1] == ']')
> > > + 	    temp = array_value (name, quoted|Q_DOUBLE_QUOTES, 0, &atype,
> > > &ind);
> > > + 	  else
> > > +--- a/subst.h	2014-10-01 18:57:43.000000000 +0200
> > > ++++ b/subst.h	2015-09-06 22:57:56.344941408 +0200
> > > +@@ -47,6 +47,7 @@
> > > + #define ASS_MKASSOC	0x0004
> > > + #define ASS_MKGLOBAL	0x0008	/* force global assignment */
> > > + #define ASS_NAMEREF	0x0010	/* assigning to nameref
> > > variable */
> > > ++#define ASS_FROMREF	0x0020	/* assigning from value of
> > > nameref
> > > variable */
> > > + 
> > > + /* Flags for the string extraction functions. */
> > > + #define SX_NOALLOC	0x0001	/* just skip; don't return
> > > substring
> > > */
> > > +--- a/variables.c	2014-10-01 18:57:51.000000000 +0200
> > > ++++ b/variables.c	2015-09-06 22:57:56.345941430 +0200
> > > +@@ -2516,10 +2516,27 @@
> > > +      HASH_TABLE *table;
> > > +      int hflags, aflags;
> > > + {
> > > +-  char *newval;
> > > ++  char *newname, *newval;
> > > +   SHELL_VAR *entry;
> > > ++#if defined (ARRAY_VARS)
> > > ++  arrayind_t ind;
> > > ++  char *subp;
> > > ++  int sublen;
> > > ++#endif
> > > + 
> > > ++  newname = 0;
> > > ++#if defined (ARRAY_VARS)
> > > ++  if ((aflags & ASS_FROMREF) && (hflags & HASH_NOSRCH) == 0 &&
> > > valid_array_reference (name))
> > > ++    {
> > > ++      newname = array_variable_name (name, &subp, &sublen);
> > > ++      if (newname == 0)
> > > ++	return (SHELL_VAR *)NULL;	/* XXX */
> > > ++      entry = hash_lookup (newname, table);
> > > ++    }
> > > ++  else
> > > ++#endif
> > > +   entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup 
> > > (name,
> > > table);
> > > ++
> > > +   /* Follow the nameref chain here if this is the global variables 
> > > table */
> > > +   if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && 
> > > table ==
> > > global_variables->table)
> > > +     {
> > > +@@ -2550,6 +2567,16 @@
> > > +       var_setvalue (entry, make_variable_value (entry, value, 0));
> > > +       }
> > > +     }
> > > ++#if defined (ARRAY_VARS)
> > > ++  else if (entry == 0 && newname)
> > > ++    {
> > > ++      entry = make_new_array_variable (newname);	/* indexed array
> > > by
> > > default */
> > > ++      if (entry == 0)
> > > ++	return entry;
> > > ++      ind = array_expand_index (name, subp, sublen);
> > > ++      bind_array_element (entry, ind, value, aflags);
> > > ++    }
> > > ++#endif
> > > +   else if (entry == 0)
> > > +     {
> > > +       entry = make_new_variable (name, table);
> > > +@@ -2670,7 +2697,8 @@
> > > + 			 normal. */
> > > + 		      if (nameref_cell (nv) == 0)
> > > + 			return (bind_variable_internal (nv->name, value,
> > > nvc->table, 0, flags));
> > > +-		      return (bind_variable_internal (nameref_cell (nv),
> > > value, nvc->table, 0, flags));
> > > ++		      /* XXX - bug here with ref=array[index] */
> > > ++		      return (bind_variable_internal (nameref_cell (nv),
> > > value, nvc->table, 0, flags|ASS_FROMREF));
> > > + 		    }
> > > + 		  else
> > > + 		    v = nv;
> > > +@@ -2805,10 +2833,12 @@
> > > + #endif
> > > +     v = bind_variable (lhs, rhs, 0);
> > > + 
> > > +-  if (v && isint)
> > > +-    VSETATTR (v, att_integer);
> > > +-
> > > +-  VUNSETATTR (v, att_invisible);
> > > ++  if (v)
> > > ++    {
> > > ++      if (isint)
> > > ++	VSETATTR (v, att_integer);
> > > ++      VUNSETATTR (v, att_invisible);
> > > ++    }
> > > + 
> > > +   return (v);
> > > + }
> > > +--- a/y.tab.c	2014-10-05 19:52:50.000000000 +0200
> > > ++++ b/y.tab.c	2015-09-06 22:58:35.247780356 +0200
> > > +@@ -5130,11 +5130,16 @@
> > > +     case AND_AND:
> > > +     case OR_OR:
> > > +     case '&':
> > > ++    case WHILE:
> > > +     case DO:
> > > ++    case UNTIL:
> > > ++    case IF:
> > > +     case THEN:
> > > ++    case ELIF:
> > > +     case ELSE:
> > > +     case '{':		/* } */
> > > +-    case '(':		/* ) */
> > > ++    case '(':		/* )( */
> > > ++    case ')':		/* only valid in case statement */
> > > +     case BANG:		/* ! time pipeline */
> > > +     case TIME:		/* time time pipeline */
> > > +     case TIMEOPT:	/* time -p time pipeline */
> > > +@@ -6015,6 +6020,8 @@
> > > + /*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", 
> > > line_number, ch,
> > > __LINE__);*/
> > > + 	      tflags |= LEX_INWORD;
> > > + 	      lex_wlen = 0;
> > > ++	      if (tflags & LEX_RESWDOK)
> > > ++		lex_rwlen = 0;
> > > + 	    }
> > > + 	}
> > > +