--- 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-2.patch | 424 +++++++++++++++++++++++++ 6 files changed, 441 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-2.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..a1ce129 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-2.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-2.patch b/src/patches/bash-4.3.30-upstream_fixes-2.patch new file mode 100644 index 0000000..2d480ec --- /dev/null +++ b/src/patches/bash-4.3.30-upstream_fixes-2.patch @@ -0,0 +1,424 @@ +Submitted By: Armin K. <krejzi at email dot com> +Date: 2015-05-23 +Initial Package Version: 4.3 +Upstream Status: Already in upstream patch repo +Origin: Upstream +Description: This patch contains upstream patch numbers 031 thru 039 + +--- a/arrayfunc.c 2014-10-01 18:57:35.000000000 +0200 ++++ b/arrayfunc.c 2015-05-21 18:21:02.877941074 +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-05-21 18:21:00.158956999 +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-05-21 18:20:20.630188508 +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; +@@ -4208,8 +4209,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-05-21 18:20:20.631188502 +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-05-21 18:20:20.631188502 +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-05-21 18:20:57.876970364 +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-05-21 18:20:20.632188497 +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/sh/unicode.c 2014-01-30 22:47:19.000000000 +0100 ++++ b/lib/sh/unicode.c 2015-05-21 18:20:58.415967207 +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-05-21 18:21:00.695953854 +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 */ +--- a/patchlevel.h 2014-10-05 19:52:50.000000000 +0200 ++++ b/patchlevel.h 2015-05-21 18:21:02.880941057 +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 39 + + #endif /* _PATCHLEVEL_H_ */ +--- a/shell.c 2014-01-14 14:04:32.000000000 +0100 ++++ b/shell.c 2015-05-21 18:20:20.632188497 +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-05-21 18:20:20.632188497 +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.h 2014-10-01 18:57:43.000000000 +0200 ++++ b/subst.h 2015-05-21 18:20:20.633188491 +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-05-21 18:20:59.606960232 +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-05-21 18:21:00.783953338 +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 */