openpkg/bash.patch.vendor

Thu, 04 Oct 2012 20:30:05 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 04 Oct 2012 20:30:05 +0200
changeset 715
c10fb90893b9
parent 428
f880f219c566
permissions
-rw-r--r--

Correct out of date build configuration, porting to Solaris 11 network
link infrastructure and new libpcap logic. This additionally allows for
device drivers in subdirectories of /dev. Correct packaged nmap
personalities and signatures to work out of the box. Finally, hack
arpd logic to properly close sockets and quit on TERM by repeating
signaling in the run command script. Sadly, all this fails to correct
the run time behaviour of honeyd which fails to bind to the IP layer.

     1 Index: assoc.c
     2 --- assoc.c.orig	2009-08-06 02:19:40.000000000 +0200
     3 +++ assoc.c	2012-06-27 10:31:02.000000000 +0200
     4 @@ -77,6 +77,11 @@
     5    b = hash_search (key, hash, HASH_CREATE);
     6    if (b == 0)
     7      return -1;
     8 +  /* If we are overwriting an existing element's value, we're not going to
     9 +     use the key.  Nothing in the array assignment code path frees the key
    10 +     string, so we can free it here to avoid a memory leak. */
    11 +  if (b->key != key)
    12 +    free (key);
    13    FREE (b->data);
    14    b->data = value ? savestring (value) : (char *)0;
    15    return (0);
    16 Index: bashline.c
    17 --- bashline.c.orig	2011-01-16 21:32:47.000000000 +0100
    18 +++ bashline.c	2012-06-27 10:31:03.000000000 +0200
    19 @@ -121,6 +121,9 @@
    20  static int filename_completion_ignore __P((char **));
    21  static int bash_push_line __P((void));
    23 +static rl_icppfunc_t *save_directory_hook __P((void));
    24 +static void reset_directory_hook __P((rl_icppfunc_t *));
    25 +
    26  static void cleanup_expansion_error __P((void));
    27  static void maybe_make_readline_line __P((char *));
    28  static void set_up_new_line __P((char *));
    29 @@ -243,10 +246,17 @@
    30  /* Perform spelling correction on directory names during word completion */
    31  int dircomplete_spelling = 0;
    33 +/* Expand directory names during word/filename completion. */
    34 +int dircomplete_expand = 0;
    35 +int dircomplete_expand_relpath = 0;
    36 +
    37  static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:";
    38  static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:";
    39  /* )) */
    41 +static const char *default_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~";	/*}*/
    42 +static char *custom_filename_quote_characters = 0;
    43 +
    44  static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL;
    46  static int dot_in_path = 0;
    47 @@ -501,7 +511,7 @@
    49    /* Tell the completer that we might want to follow symbolic links or
    50       do other expansion on directory names. */
    51 -  rl_directory_rewrite_hook = bash_directory_completion_hook;
    52 +  set_directory_hook ();
    54    rl_filename_rewrite_hook = bash_filename_rewrite_hook;
    56 @@ -529,7 +539,7 @@
    57    enable_hostname_completion (perform_hostname_completion);
    59    /* characters that need to be quoted when appearing in filenames. */
    60 -  rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~";	/*}*/
    61 +  rl_filename_quote_characters = default_filename_quote_characters;
    63    rl_filename_quoting_function = bash_quote_filename;
    64    rl_filename_dequoting_function = bash_dequote_filename;
    65 @@ -564,8 +574,10 @@
    66    tilde_initialize ();
    67    rl_attempted_completion_function = attempt_shell_completion;
    68    rl_completion_entry_function = NULL;
    69 -  rl_directory_rewrite_hook = bash_directory_completion_hook;
    70    rl_ignore_some_completions_function = filename_completion_ignore;
    71 +  rl_filename_quote_characters = default_filename_quote_characters;
    72 +
    73 +  set_directory_hook ();
    74  }
    76  /* Contains the line to push into readline. */
    77 @@ -1279,6 +1291,9 @@
    78    matches = (char **)NULL;
    79    rl_ignore_some_completions_function = filename_completion_ignore;
    81 +  rl_filename_quote_characters = default_filename_quote_characters;
    82 +  set_directory_hook ();
    83 +
    84    /* Determine if this could be a command word.  It is if it appears at
    85       the start of the line (ignoring preceding whitespace), or if it
    86       appears after a character that separates commands.  It cannot be a
    87 @@ -1591,6 +1606,12 @@
    88  	    }
    89  	  else
    90  	    {
    91 +	     if (dircomplete_expand && dot_or_dotdot (filename_hint))
    92 +		{
    93 +		  dircomplete_expand = 0;
    94 +		  set_directory_hook ();
    95 +		  dircomplete_expand = 1;
    96 +		}
    97  	      mapping_over = 4;
    98  	      goto inner;
    99  	    }
   100 @@ -1791,6 +1812,9 @@
   102   inner:
   103    val = rl_filename_completion_function (filename_hint, istate);
   104 +  if (mapping_over == 4 && dircomplete_expand)
   105 +    set_directory_hook ();
   106 +
   107    istate = 1;
   109    if (val == 0)
   110 @@ -2693,6 +2717,52 @@
   111    return conv;
   112  }
   114 +/* Functions to save and restore the appropriate directory hook */
   115 +/* This is not static so the shopt code can call it */
   116 +void
   117 +set_directory_hook ()
   118 +{
   119 +  if (dircomplete_expand)
   120 +    {
   121 +      rl_directory_completion_hook = bash_directory_completion_hook;
   122 +      rl_directory_rewrite_hook = (rl_icppfunc_t *)0;
   123 +    }
   124 +  else
   125 +    {
   126 +      rl_directory_rewrite_hook = bash_directory_completion_hook;
   127 +      rl_directory_completion_hook = (rl_icppfunc_t *)0;
   128 +    }
   129 +}
   130 +
   131 +static rl_icppfunc_t *
   132 +save_directory_hook ()
   133 +{
   134 +  rl_icppfunc_t *ret;
   135 +
   136 +  if (dircomplete_expand)
   137 +    {
   138 +      ret = rl_directory_completion_hook;
   139 +      rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
   140 +    }
   141 +  else
   142 +    {
   143 +      ret = rl_directory_rewrite_hook;
   144 +      rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
   145 +    }
   146 +
   147 +  return ret;
   148 +}
   149 +
   150 +static void
   151 +restore_directory_hook (hookf)
   152 +     rl_icppfunc_t *hookf;
   153 +{
   154 +  if (dircomplete_expand)
   155 +    rl_directory_completion_hook = hookf;
   156 +  else
   157 +    rl_directory_rewrite_hook = hookf;
   158 +}
   159 +
   160  /* Handle symbolic link references and other directory name
   161     expansions while hacking completion.  This should return 1 if it modifies
   162     the DIRNAME argument, 0 otherwise.  It should make sure not to modify
   163 @@ -2702,20 +2772,31 @@
   164       char **dirname;
   165  {
   166    char *local_dirname, *new_dirname, *t;
   167 -  int return_value, should_expand_dirname;
   168 +  int return_value, should_expand_dirname, nextch, closer;
   169    WORD_LIST *wl;
   170    struct stat sb;
   172 -  return_value = should_expand_dirname = 0;
   173 +  return_value = should_expand_dirname = nextch = closer = 0;
   174    local_dirname = *dirname;
   176 -  if (mbschr (local_dirname, '$'))
   177 -    should_expand_dirname = 1;
   178 +  if (t = mbschr (local_dirname, '$'))
   179 +    {
   180 +      should_expand_dirname = '$';
   181 +      nextch = t[1];
   182 +      /* Deliberately does not handle the deprecated $[...] arithmetic
   183 +	 expansion syntax */
   184 +      if (nextch == '(')
   185 +	closer = ')';
   186 +      else if (nextch == '{')
   187 +	closer = '}';
   188 +      else
   189 +	nextch = 0;
   190 +    }
   191    else
   192      {
   193        t = mbschr (local_dirname, '`');
   194        if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0)
   195 -	should_expand_dirname = 1;
   196 +	should_expand_dirname = '`';
   197      }
   199  #if defined (HAVE_LSTAT)
   200 @@ -2739,6 +2820,23 @@
   201  	  free (new_dirname);
   202  	  dispose_words (wl);
   203  	  local_dirname = *dirname;
   204 +	  /* XXX - change rl_filename_quote_characters here based on
   205 +	     should_expand_dirname/nextch/closer.  This is the only place
   206 +	     custom_filename_quote_characters is modified. */
   207 +	  if (rl_filename_quote_characters && *rl_filename_quote_characters)
   208 +	    {
   209 +	      int i, j, c;
   210 +	      i = strlen (default_filename_quote_characters);
   211 +	      custom_filename_quote_characters = xrealloc (custom_filename_quote_characters, i+1);
   212 +	      for (i = j = 0; c = default_filename_quote_characters[i]; i++)
   213 +		{
   214 +		  if (c == should_expand_dirname || c == nextch || c == closer)
   215 +		    continue;
   216 +		  custom_filename_quote_characters[j++] = c;
   217 +		}
   218 +	      custom_filename_quote_characters[j] = '\0';
   219 +	      rl_filename_quote_characters = custom_filename_quote_characters;
   220 +	    }
   221  	}
   222        else
   223  	{
   224 @@ -2758,11 +2856,31 @@
   225        local_dirname = *dirname = new_dirname;
   226      }
   228 +  /* no_symbolic_links == 0 -> use (default) logical view of the file system.
   229 +     local_dirname[0] == '.' && local_dirname[1] == '/' means files in the
   230 +     current directory (./).
   231 +     local_dirname[0] == '.' && local_dirname[1] == 0 means relative pathnames
   232 +     in the current directory (e.g., lib/sh).
   233 +     XXX - should we do spelling correction on these? */
   234 +
   235 +  /* This is test as it was in bash-4.2: skip relative pathnames in current
   236 +     directory.  Change test to
   237 +      (local_dirname[0] != '.' || (local_dirname[1] && local_dirname[1] != '/'))
   238 +     if we want to skip paths beginning with ./ also. */
   239    if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1]))
   240      {
   241        char *temp1, *temp2;
   242        int len1, len2;
   244 +      /* If we have a relative path
   245 +      		(local_dirname[0] != '/' && local_dirname[0] != '.')
   246 +	 that is canonical after appending it to the current directory, then
   247 +	 	temp1 = temp2+'/'
   248 +	 That is,
   249 +	 	strcmp (temp1, temp2) == 0
   250 +	 after adding a slash to temp2 below.  It should be safe to not
   251 +	 change those.
   252 +      */
   253        t = get_working_directory ("symlink-hook");
   254        temp1 = make_absolute (local_dirname, t);
   255        free (t);
   256 @@ -2797,7 +2915,15 @@
   257  	      temp2[len2 + 1] = '\0';
   258  	    }
   259  	}
   260 -      return_value |= STREQ (local_dirname, temp2) == 0;
   261 +
   262 +      /* dircomplete_expand_relpath == 0 means we want to leave relative
   263 +	 pathnames that are unchanged by canonicalization alone.
   264 +	 *local_dirname != '/' && *local_dirname != '.' == relative pathname
   265 +	 (consistent with general.c:absolute_pathname())
   266 +	 temp1 == temp2 (after appending a slash to temp2) means the pathname
   267 +	 is not changed by canonicalization as described above. */
   268 +      if (dircomplete_expand_relpath || ((local_dirname[0] != '/' && local_dirname[0] != '.') && STREQ (temp1, temp2) == 0))
   269 +	return_value |= STREQ (local_dirname, temp2) == 0;
   270        free (local_dirname);
   271        *dirname = temp2;
   272        free (temp1);
   273 @@ -3002,12 +3128,13 @@
   275    orig_func = rl_completion_entry_function;
   276    orig_attempt_func = rl_attempted_completion_function;
   277 -  orig_dir_func = rl_directory_rewrite_hook;
   278    orig_ignore_func = rl_ignore_some_completions_function;
   279    orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
   280 +
   281 +  orig_dir_func = save_directory_hook ();
   282 +
   283    rl_completion_entry_function = rl_filename_completion_function;
   284    rl_attempted_completion_function = (rl_completion_func_t *)NULL;
   285 -  rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
   286    rl_ignore_some_completions_function = filename_completion_ignore;
   287    rl_completer_word_break_characters = " \t\n\"\'";
   289 @@ -3015,10 +3142,11 @@
   291    rl_completion_entry_function = orig_func;
   292    rl_attempted_completion_function = orig_attempt_func;
   293 -  rl_directory_rewrite_hook = orig_dir_func;
   294    rl_ignore_some_completions_function = orig_ignore_func;
   295    rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
   297 +  restore_directory_hook (orig_dir_func);
   298 +
   299    return r;
   300  }
   302 Index: bashline.h
   303 --- bashline.h.orig	2009-01-04 20:32:22.000000000 +0100
   304 +++ bashline.h	2012-06-27 10:31:03.000000000 +0200
   305 @@ -33,10 +33,15 @@
   306  extern void bashline_reinitialize __P((void));
   307  extern int bash_re_edit __P((char *));
   309 +extern void bashline_set_event_hook __P((void));
   310 +extern void bashline_reset_event_hook __P((void));
   311 +
   312  extern int bind_keyseq_to_unix_command __P((char *));
   314  extern char **bash_default_completion __P((const char *, int, int, int, int));
   316 +void set_directory_hook __P((void));
   317 +
   318  /* Used by programmable completion code. */
   319  extern char *command_word_completion_function __P((const char *, int));
   320  extern char *bash_groupname_completion_function __P((const char *, int));
   321 Index: builtins/declare.def
   322 --- builtins/declare.def.orig	2010-05-31 00:25:21.000000000 +0200
   323 +++ builtins/declare.def	2012-06-27 10:31:02.000000000 +0200
   324 @@ -513,6 +513,11 @@
   325  	      *subscript_start = '[';	/* ] */
   326  	      var = assign_array_element (name, value, 0);	/* XXX - not aflags */
   327  	      *subscript_start = '\0';
   328 +	      if (var == 0)	/* some kind of assignment error */
   329 +		{
   330 +		  assign_error++;
   331 +		  NEXT_VARIABLE ();
   332 +		}
   333  	    }
   334  	  else if (simple_array_assign)
   335  	    {
   336 Index: builtins/fc.def
   337 --- builtins/fc.def.orig	2010-05-31 00:25:38.000000000 +0200
   338 +++ builtins/fc.def	2012-06-27 10:31:02.000000000 +0200
   339 @@ -304,7 +304,7 @@
   340    last_hist = i - rh - hist_last_line_added;
   342    /* XXX */
   343 -  if (saved_command_line_count > 0 && i == last_hist && hlist[last_hist] == 0)
   344 +  if (i == last_hist && hlist[last_hist] == 0)
   345      while (last_hist >= 0 && hlist[last_hist] == 0)
   346        last_hist--;
   347    if (last_hist < 0)
   348 @@ -475,7 +475,7 @@
   349       HIST_ENTRY **hlist;
   350  {
   351    int sign, n, clen, rh;
   352 -  register int i, j;
   353 +  register int i, j, last_hist;
   354    register char *s;
   356    sign = 1;
   357 @@ -495,7 +495,15 @@
   358       has been enabled (interactive or not) should use it in the last_hist
   359       calculation as if it were on. */
   360    rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
   361 -  i -= rh + hist_last_line_added;
   362 +  last_hist = i - rh - hist_last_line_added;
   363 +
   364 +  if (i == last_hist && hlist[last_hist] == 0)
   365 +    while (last_hist >= 0 && hlist[last_hist] == 0)
   366 +      last_hist--;
   367 +  if (last_hist < 0)
   368 +    return (-1);
   369 +
   370 +  i = last_hist;
   372    /* No specification defaults to most recent command. */
   373    if (command == NULL)
   374 Index: builtins/printf.def
   375 --- builtins/printf.def.orig	2010-11-23 16:02:55.000000000 +0100
   376 +++ builtins/printf.def	2012-06-27 10:31:02.000000000 +0200
   377 @@ -255,6 +255,8 @@
   378  #endif
   379  	    {
   380  	      vflag = 1;
   381 +	      if (vbsize == 0)
   382 +		vbuf = xmalloc (vbsize = 16);
   383  	      vblen = 0;
   384  	      if (vbuf)
   385  		vbuf[0] = 0;
   386 @@ -465,6 +467,9 @@
   387  		  secs = shell_start_time;	/* roughly $SECONDS */
   388  		else
   389  		  secs = arg;
   390 +#if defined (HAVE_TZSET)
   391 +		sv_tz ("TZ");		/* XXX -- just make sure */
   392 +#endif
   393  		tm = localtime (&secs);
   394  		n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
   395  		free (timefmt);
   396 Index: builtins/read.def
   397 --- builtins/read.def.orig	2011-01-04 17:43:36.000000000 +0100
   398 +++ builtins/read.def	2012-06-27 10:31:02.000000000 +0200
   399 @@ -642,6 +642,12 @@
   400  	  xfree (input_string);
   401  	  return EXECUTION_FAILURE;	/* readonly or noassign */
   402  	}
   403 +      if (assoc_p (var))
   404 +	{
   405 +          builtin_error (_("%s: cannot convert associative to indexed array"), arrayname);
   406 +	  xfree (input_string);
   407 +	  return EXECUTION_FAILURE;	/* existing associative array */
   408 +	}
   409        array_flush (array_cell (var));
   411        alist = list_string (input_string, ifs_chars, 0);
   412 @@ -731,7 +737,7 @@
   413  	      xfree (t1);
   414  	    }
   415  	  else
   416 -	    var = bind_read_variable (varname, t);
   417 +	    var = bind_read_variable (varname, t ? t : "");
   418  	}
   419        else
   420  	{
   421 @@ -792,7 +798,7 @@
   422        xfree (t);
   423      }
   424    else
   425 -    var = bind_read_variable (list->word->word, input_string);
   426 +    var = bind_read_variable (list->word->word, input_string ? input_string : "");
   428    if (var)
   429      {
   430 Index: builtins/shopt.def
   431 --- builtins/shopt.def.orig	2010-07-03 04:42:44.000000000 +0200
   432 +++ builtins/shopt.def	2012-06-27 10:31:03.000000000 +0200
   433 @@ -61,6 +61,10 @@
   434  #include "common.h"
   435  #include "bashgetopt.h"
   437 +#if defined (READLINE)
   438 +#  include "../bashline.h"
   439 +#endif
   440 +
   441  #if defined (HISTORY)
   442  #  include "../bashhist.h"
   443  #endif
   444 @@ -94,7 +98,7 @@
   445  extern int hist_verify, history_reediting, perform_hostname_completion;
   446  extern int no_empty_command_completion;
   447  extern int force_fignore;
   448 -extern int dircomplete_spelling;
   449 +extern int dircomplete_spelling, dircomplete_expand;
   451  extern int enable_hostname_completion __P((int));
   452  #endif
   453 @@ -121,6 +125,10 @@
   454  static int set_restricted_shell __P((char *, int));
   455  #endif
   457 +#if defined (READLINE)
   458 +static int shopt_set_complete_direxpand __P((char *, int));
   459 +#endif
   460 +
   461  static int shopt_login_shell;
   462  static int shopt_compat31;
   463  static int shopt_compat32;
   464 @@ -150,6 +158,7 @@
   465    { "compat40", &shopt_compat40, set_compatibility_level },
   466    { "compat41", &shopt_compat41, set_compatibility_level },
   467  #if defined (READLINE)
   468 +  { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
   469    { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
   470  #endif
   471    { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
   472 @@ -535,6 +544,17 @@
   473    return 0;
   474  }
   476 +#if defined (READLINE)
   477 +static int
   478 +shopt_set_complete_direxpand (option_name, mode)
   479 +     char *option_name;
   480 +     int mode;
   481 +{
   482 +  set_directory_hook ();
   483 +  return 0;
   484 +}
   485 +#endif
   486 +
   487  #if defined (RESTRICTED_SHELL)
   488  /* Don't allow the value of restricted_shell to be modified. */
   490 Index: command.h
   491 --- command.h.orig	2010-08-03 01:36:51.000000000 +0200
   492 +++ command.h	2012-06-27 10:31:02.000000000 +0200
   493 @@ -97,6 +97,7 @@
   494  #define W_HASCTLESC	0x200000	/* word contains literal CTLESC characters */
   495  #define W_ASSIGNASSOC	0x400000	/* word looks like associative array assignment */
   496  #define W_ARRAYIND	0x800000	/* word is an array index being expanded */
   497 +#define W_ASSNGLOBAL	0x1000000	/* word is a global assignment to declare (declare/typeset -g) */
   499  /* Possible values for subshell_environment */
   500  #define SUBSHELL_ASYNC	0x01	/* subshell caused by `command &' */
   501 Index: doc/bash.1
   502 --- doc/bash.1.orig	2011-01-16 21:31:39.000000000 +0100
   503 +++ doc/bash.1	2012-06-27 10:31:03.000000000 +0200
   504 @@ -8954,6 +8954,16 @@
   505  quoted.  This is the behavior of posix mode through version 4.1.
   506  The default bash behavior remains as in previous versions.
   507  .TP 8
   508 +.B direxpand
   509 +If set,
   510 +.B bash
   511 +replaces directory names with the results of word expansion when performing
   512 +filename completion.  This changes the contents of the readline editing
   513 +buffer.
   514 +If not set,
   515 +.B bash
   516 +attempts to preserve what the user typed.
   517 +.TP 8
   518  .B dirspell
   519  If set,
   520  .B bash
   521 Index: doc/bashref.texi
   522 --- doc/bashref.texi.orig	2011-01-16 21:31:57.000000000 +0100
   523 +++ doc/bashref.texi	2012-06-27 10:31:03.000000000 +0200
   524 @@ -4535,6 +4535,13 @@
   525  quoted.  This is the behavior of @sc{posix} mode through version 4.1.
   526  The default Bash behavior remains as in previous versions.
   528 +@item direxpand
   529 +If set, Bash
   530 +replaces directory names with the results of word expansion when performing
   531 +filename completion.  This changes the contents of the readline editing
   532 +buffer.
   533 +If not set, Bash attempts to preserve what the user typed.
   534 +
   535  @item dirspell
   536  If set, Bash
   537  attempts spelling correction on directory names during word completion 
   538 Index: error.c
   539 --- error.c.orig	2009-08-22 04:31:31.000000000 +0200
   540 +++ error.c	2012-06-27 10:31:02.000000000 +0200
   541 @@ -200,7 +200,11 @@
   543    va_end (args);
   544    if (exit_immediately_on_error)
   545 -    exit_shell (1);
   546 +    {
   547 +      if (last_command_exit_value == 0)
   548 +	last_command_exit_value = 1;
   549 +      exit_shell (last_command_exit_value);
   550 +    }
   551  }
   553  void
   554 Index: execute_cmd.c
   555 --- execute_cmd.c.orig	2011-02-09 23:32:25.000000000 +0100
   556 +++ execute_cmd.c	2012-06-27 10:31:03.000000000 +0200
   557 @@ -2196,6 +2196,7 @@
   558    if (ignore_return && cmd)
   559      cmd->flags |= CMD_IGNORE_RETURN;
   561 +#if defined (JOB_CONTROL)
   562    lastpipe_flag = 0;
   563    begin_unwind_frame ("lastpipe-exec");
   564    lstdin = -1;
   565 @@ -2204,7 +2205,7 @@
   566       current shell environment. */
   567    if (lastpipe_opt && job_control == 0 && asynchronous == 0 && pipe_out == NO_PIPE && prev > 0)
   568      {
   569 -      lstdin = move_to_high_fd (0, 0, 255);
   570 +      lstdin = move_to_high_fd (0, 1, -1);
   571        if (lstdin > 0)
   572  	{
   573  	  do_piping (prev, pipe_out);
   574 @@ -2215,15 +2216,19 @@
   575  	  lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL);	/* XXX */
   576  	  add_unwind_protect (lastpipe_cleanup, lastpipe_jid);
   577  	}
   578 -      cmd->flags |= CMD_LASTPIPE;
   579 +      if (cmd)
   580 +	cmd->flags |= CMD_LASTPIPE;
   581      }	  
   582    if (prev >= 0)
   583      add_unwind_protect (close, prev);
   584 +#endif
   586    exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close);
   588 +#if defined (JOB_CONTROL)
   589    if (lstdin > 0)
   590      restore_stdin (lstdin);
   591 +#endif
   593    if (prev >= 0)
   594      close (prev);
   595 @@ -2246,7 +2251,9 @@
   596        unfreeze_jobs_list ();
   597      }
   599 +#if defined (JOB_CONTROL)
   600    discard_unwind_frame ("lastpipe-exec");
   601 +#endif
   603    return (exec_result);
   604  }
   605 @@ -3575,13 +3582,13 @@
   606  {
   607    WORD_LIST *w;
   608    struct builtin *b;
   609 -  int assoc;
   610 +  int assoc, global;
   612    if (words == 0)
   613      return;
   615    b = 0;
   616 -  assoc = 0;
   617 +  assoc = global = 0;
   619    for (w = words; w; w = w->next)
   620      if (w->word->flags & W_ASSIGNMENT)
   621 @@ -3598,12 +3605,17 @@
   622  #if defined (ARRAY_VARS)
   623  	if (assoc)
   624  	  w->word->flags |= W_ASSIGNASSOC;
   625 +	if (global)
   626 +	  w->word->flags |= W_ASSNGLOBAL;
   627  #endif
   628        }
   629  #if defined (ARRAY_VARS)
   630      /* Note that we saw an associative array option to a builtin that takes
   631         assignment statements.  This is a bit of a kludge. */
   632 -    else if (w->word->word[0] == '-' && strchr (w->word->word, 'A'))
   633 +    else if (w->word->word[0] == '-' && (strchr (w->word->word+1, 'A') || strchr (w->word->word+1, 'g')))
   634 +#else
   635 +    else if (w->word->word[0] == '-' && strchr (w->word->word+1, 'g'))
   636 +#endif
   637        {
   638  	if (b == 0)
   639  	  {
   640 @@ -3613,10 +3625,11 @@
   641  	    else if (b && (b->flags & ASSIGNMENT_BUILTIN))
   642  	      words->word->flags |= W_ASSNBLTIN;
   643  	  }
   644 -	if (words->word->flags & W_ASSNBLTIN)
   645 +	if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'A'))
   646  	  assoc = 1;
   647 +	if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'g'))
   648 +	  global = 1;
   649        }
   650 -#endif
   651  }
   653  /* Return 1 if the file found by searching $PATH for PATHNAME, defaulting
   654 Index: expr.c
   655 --- expr.c.orig	2010-12-21 17:12:13.000000000 +0100
   656 +++ expr.c	2012-06-27 10:31:02.000000000 +0200
   657 @@ -476,19 +476,23 @@
   659        if (special)
   660  	{
   661 +	  if ((op == DIV || op == MOD) && value == 0)
   662 +	    {
   663 +	      if (noeval == 0)
   664 +		evalerror (_("division by 0"));
   665 +	      else
   666 +	        value = 1;
   667 +	    }
   668 +
   669  	  switch (op)
   670  	    {
   671  	    case MUL:
   672  	      lvalue *= value;
   673  	      break;
   674  	    case DIV:
   675 -	      if (value == 0)
   676 -		evalerror (_("division by 0"));
   677  	      lvalue /= value;
   678  	      break;
   679  	    case MOD:
   680 -	      if (value == 0)
   681 -		evalerror (_("division by 0"));
   682  	      lvalue %= value;
   683  	      break;
   684  	    case PLUS:
   685 @@ -804,7 +808,12 @@
   686        val2 = exppower ();
   688        if (((op == DIV) || (op == MOD)) && (val2 == 0))
   689 -	evalerror (_("division by 0"));
   690 +	{
   691 +	  if (noeval == 0)
   692 +	    evalerror (_("division by 0"));
   693 +	  else
   694 +	    val2 = 1;
   695 +	}
   697        if (op == MUL)
   698  	val1 *= val2;
   699 Index: lib/glob/gmisc.c
   700 --- lib/glob/gmisc.c.orig	2011-02-05 22:11:17.000000000 +0100
   701 +++ lib/glob/gmisc.c	2012-06-27 10:31:02.000000000 +0200
   702 @@ -77,8 +77,8 @@
   703       wchar_t *wpat;
   704       size_t wmax;
   705  {
   706 -  wchar_t wc, *wbrack;
   707 -  int matlen, t, in_cclass, in_collsym, in_equiv;
   708 +  wchar_t wc;
   709 +  int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
   711    if (*wpat == 0)
   712      return (0);
   713 @@ -118,58 +118,80 @@
   714  	  break;
   715  	case L'[':
   716  	  /* scan for ending `]', skipping over embedded [:...:] */
   717 -	  wbrack = wpat;
   718 +	  bracklen = 1;
   719  	  wc = *wpat++;
   720  	  do
   721  	    {
   722  	      if (wc == 0)
   723  		{
   724 -	          matlen += wpat - wbrack - 1;	/* incremented below */
   725 -	          break;
   726 +		  wpat--;			/* back up to NUL */
   727 +	          matlen += bracklen;
   728 +	          goto bad_bracket;
   729  	        }
   730  	      else if (wc == L'\\')
   731  		{
   732 -		  wc = *wpat++;
   733 -		  if (*wpat == 0)
   734 -		    break;
   735 +		  /* *wpat == backslash-escaped character */
   736 +		  bracklen++;
   737 +		  /* If the backslash or backslash-escape ends the string,
   738 +		     bail.  The ++wpat skips over the backslash escape */
   739 +		  if (*wpat == 0 || *++wpat == 0)
   740 +		    {
   741 +		      matlen += bracklen;
   742 +		      goto bad_bracket;
   743 +		    }
   744  		}
   745  	      else if (wc == L'[' && *wpat == L':')	/* character class */
   746  		{
   747  		  wpat++;
   748 +		  bracklen++;
   749  		  in_cclass = 1;
   750  		}
   751  	      else if (in_cclass && wc == L':' && *wpat == L']')
   752  		{
   753  		  wpat++;
   754 +		  bracklen++;
   755  		  in_cclass = 0;
   756  		}
   757  	      else if (wc == L'[' && *wpat == L'.')	/* collating symbol */
   758  		{
   759  		  wpat++;
   760 +		  bracklen++;
   761  		  if (*wpat == L']')	/* right bracket can appear as collating symbol */
   762 -		    wpat++;
   763 +		    {
   764 +		      wpat++;
   765 +		      bracklen++;
   766 +		    }
   767  		  in_collsym = 1;
   768  		}
   769  	      else if (in_collsym && wc == L'.' && *wpat == L']')
   770  		{
   771  		  wpat++;
   772 +		  bracklen++;
   773  		  in_collsym = 0;
   774  		}
   775  	      else if (wc == L'[' && *wpat == L'=')	/* equivalence class */
   776  		{
   777  		  wpat++;
   778 +		  bracklen++;
   779  		  if (*wpat == L']')	/* right bracket can appear as equivalence class */
   780 -		    wpat++;
   781 +		    {
   782 +		      wpat++;
   783 +		      bracklen++;
   784 +		    }
   785  		  in_equiv = 1;
   786  		}
   787  	      else if (in_equiv && wc == L'=' && *wpat == L']')
   788  		{
   789  		  wpat++;
   790 +		  bracklen++;
   791  		  in_equiv = 0;
   792  		}
   793 +	      else
   794 +		bracklen++;
   795  	    }
   796  	  while ((wc = *wpat++) != L']');
   797  	  matlen++;		/* bracket expression can only match one char */
   798 +bad_bracket:
   799  	  break;
   800  	}
   801      }
   802 @@ -213,8 +235,8 @@
   803       char *pat;
   804       size_t max;
   805  {
   806 -  char c, *brack;
   807 -  int matlen, t, in_cclass, in_collsym, in_equiv;
   808 +  char c;
   809 +  int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
   811    if (*pat == 0)
   812      return (0);
   813 @@ -254,58 +276,80 @@
   814  	  break;
   815  	case '[':
   816  	  /* scan for ending `]', skipping over embedded [:...:] */
   817 -	  brack = pat;
   818 +	  bracklen = 1;
   819  	  c = *pat++;
   820  	  do
   821  	    {
   822  	      if (c == 0)
   823  		{
   824 -	          matlen += pat - brack - 1;	/* incremented below */
   825 -	          break;
   826 +		  pat--;			/* back up to NUL */
   827 +		  matlen += bracklen;
   828 +		  goto bad_bracket;
   829  	        }
   830  	      else if (c == '\\')
   831  		{
   832 -		  c = *pat++;
   833 -		  if (*pat == 0)
   834 -		    break;
   835 +		  /* *pat == backslash-escaped character */
   836 +		  bracklen++;
   837 +		  /* If the backslash or backslash-escape ends the string,
   838 +		     bail.  The ++pat skips over the backslash escape */
   839 +		  if (*pat == 0 || *++pat == 0)
   840 +		    {
   841 +		      matlen += bracklen;
   842 +		      goto bad_bracket;
   843 +		    }
   844  		}
   845  	      else if (c == '[' && *pat == ':')	/* character class */
   846  		{
   847  		  pat++;
   848 +		  bracklen++;
   849  		  in_cclass = 1;
   850  		}
   851  	      else if (in_cclass && c == ':' && *pat == ']')
   852  		{
   853  		  pat++;
   854 +		  bracklen++;
   855  		  in_cclass = 0;
   856  		}
   857  	      else if (c == '[' && *pat == '.')	/* collating symbol */
   858  		{
   859  		  pat++;
   860 +		  bracklen++;
   861  		  if (*pat == ']')	/* right bracket can appear as collating symbol */
   862 -		    pat++;
   863 +		    {
   864 +		      pat++;
   865 +		      bracklen++;
   866 +		    }
   867  		  in_collsym = 1;
   868  		}
   869  	      else if (in_collsym && c == '.' && *pat == ']')
   870  		{
   871  		  pat++;
   872 +		  bracklen++;
   873  		  in_collsym = 0;
   874  		}
   875  	      else if (c == '[' && *pat == '=')	/* equivalence class */
   876  		{
   877  		  pat++;
   878 +		  bracklen++;
   879  		  if (*pat == ']')	/* right bracket can appear as equivalence class */
   880 -		    pat++;
   881 +		    {
   882 +		      pat++;
   883 +		      bracklen++;
   884 +		    }
   885  		  in_equiv = 1;
   886  		}
   887  	      else if (in_equiv && c == '=' && *pat == ']')
   888  		{
   889  		  pat++;
   890 +		  bracklen++;
   891  		  in_equiv = 0;
   892  		}
   893 +	      else
   894 +		bracklen++;
   895  	    }
   896  	  while ((c = *pat++) != ']');
   897  	  matlen++;		/* bracket expression can only match one char */
   898 +bad_bracket:
   899  	  break;
   900  	}
   901      }
   902 Index: lib/readline/callback.c
   903 --- lib/readline/callback.c.orig	2010-06-06 18:18:58.000000000 +0200
   904 +++ lib/readline/callback.c	2012-06-27 10:31:02.000000000 +0200
   905 @@ -148,6 +148,9 @@
   906  	  eof = _rl_vi_domove_callback (_rl_vimvcxt);
   907  	  /* Should handle everything, including cleanup, numeric arguments,
   908  	     and turning off RL_STATE_VIMOTION */
   909 +	  if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
   910 +	    _rl_internal_char_cleanup ();
   911 +
   912  	  return;
   913  	}
   914  #endif
   915 Index: lib/readline/vi_mode.c
   916 --- lib/readline/vi_mode.c.orig	2010-11-21 01:51:39.000000000 +0100
   917 +++ lib/readline/vi_mode.c	2012-06-27 10:31:02.000000000 +0200
   918 @@ -1114,7 +1114,7 @@
   919        rl_beg_of_line (1, c);
   920        _rl_vi_last_motion = c;
   921        RL_UNSETSTATE (RL_STATE_VIMOTION);
   922 -      return (0);
   923 +      return (vidomove_dispatch (m));
   924      }
   925  #if defined (READLINE_CALLBACKS)
   926    /* XXX - these need to handle rl_universal_argument bindings */
   927 Index: lib/sh/zread.c
   928 --- lib/sh/zread.c.orig	2009-03-02 14:54:45.000000000 +0100
   929 +++ lib/sh/zread.c	2012-06-27 10:31:02.000000000 +0200
   930 @@ -160,14 +160,13 @@
   931  zsyncfd (fd)
   932       int fd;
   933  {
   934 -  off_t off;
   935 -  int r;
   936 +  off_t off, r;
   938    off = lused - lind;
   939    r = 0;
   940    if (off > 0)
   941      r = lseek (fd, -off, SEEK_CUR);
   943 -  if (r >= 0)
   944 +  if (r != -1)
   945      lused = lind = 0;
   946  }
   947 Index: parse.y
   948 --- parse.y.orig	2011-01-02 21:48:11.000000000 +0100
   949 +++ parse.y	2012-06-27 10:31:02.000000000 +0200
   950 @@ -2499,7 +2499,7 @@
   951  	 We do this only if it is time to do so. Notice that only here
   952  	 is the mail alarm reset; nothing takes place in check_mail ()
   953  	 except the checking of mail.  Please don't change this. */
   954 -      if (prompt_is_ps1 && time_to_check_mail ())
   955 +      if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ())
   956  	{
   957  	  check_mail ();
   958  	  reset_mail_timer ();
   959 @@ -3842,6 +3842,7 @@
   960       int flags;
   961  {
   962    sh_parser_state_t ps;
   963 +  sh_input_line_state_t ls;
   964    int orig_ind, nc, sflags;
   965    char *ret, *s, *ep, *ostring;
   967 @@ -3849,10 +3850,12 @@
   968    orig_ind = *indp;
   969    ostring = string;
   971 +/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/
   972    sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
   973    if (flags & SX_NOLONGJMP)
   974      sflags |= SEVAL_NOLONGJMP;
   975    save_parser_state (&ps);
   976 +  save_input_line_state (&ls);
   978    /*(*/
   979    parser_state |= PST_CMDSUBST|PST_EOFTOKEN;	/* allow instant ')' */ /*(*/
   980 @@ -3861,6 +3864,8 @@
   982    restore_parser_state (&ps);
   983    reset_parser ();
   984 +  /* reset_parser clears shell_input_line and associated variables */
   985 +  restore_input_line_state (&ls);
   986    if (interactive)
   987      token_to_read = 0;
   989 @@ -5135,6 +5140,9 @@
   990  	    case 'A':
   991  	      /* Make the current time/date into a string. */
   992  	      (void) time (&the_time);
   993 +#if defined (HAVE_TZSET)
   994 +	      sv_tz ("TZ");		/* XXX -- just make sure */
   995 +#endif
   996  	      tm = localtime (&the_time);
   998  	      if (c == 'd')
   999 @@ -5905,6 +5913,12 @@
  1000    ps->expand_aliases = expand_aliases;
  1001    ps->echo_input_at_read = echo_input_at_read;
  1003 +  ps->token = token;
  1004 +  ps->token_buffer_size = token_buffer_size;
  1005 +  /* Force reallocation on next call to read_token_word */
  1006 +  token = 0;
  1007 +  token_buffer_size = 0;
  1009    return (ps);
  1012 @@ -5946,6 +5960,42 @@
  1014    expand_aliases = ps->expand_aliases;
  1015    echo_input_at_read = ps->echo_input_at_read;
  1017 +  FREE (token);
  1018 +  token = ps->token;
  1019 +  token_buffer_size = ps->token_buffer_size;
  1020 +}
  1022 +sh_input_line_state_t *
  1023 +save_input_line_state (ls)
  1024 +     sh_input_line_state_t *ls;
  1025 +{
  1026 +  if (ls == 0)
  1027 +    ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
  1028 +  if (ls == 0)
  1029 +    return ((sh_input_line_state_t *)NULL);
  1031 +  ls->input_line = shell_input_line;
  1032 +  ls->input_line_size = shell_input_line_size;
  1033 +  ls->input_line_len = shell_input_line_len;
  1034 +  ls->input_line_index = shell_input_line_index;
  1036 +  /* force reallocation */
  1037 +  shell_input_line = 0;
  1038 +  shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
  1039 +}
  1041 +void
  1042 +restore_input_line_state (ls)
  1043 +     sh_input_line_state_t *ls;
  1044 +{
  1045 +  FREE (shell_input_line);
  1046 +  shell_input_line = ls->input_line;
  1047 +  shell_input_line_size = ls->input_line_size;
  1048 +  shell_input_line_len = ls->input_line_len;
  1049 +  shell_input_line_index = ls->input_line_index;
  1051 +  set_line_mbstate ();
  1054  /************************************************
  1055 Index: patchlevel.h
  1056 --- patchlevel.h.orig	2010-06-13 02:14:48.000000000 +0200
  1057 +++ patchlevel.h	2012-06-27 10:31:03.000000000 +0200
  1058 @@ -25,6 +25,6 @@
  1059     regexp `^#define[ 	]*PATCHLEVEL', since that's what support/mkversion.sh
  1060     looks for to find the patch level (for the sccs version string). */
  1062 -#define PATCHLEVEL 0
  1063 +#define PATCHLEVEL 29
  1065  #endif /* _PATCHLEVEL_H_ */
  1066 Index: pathexp.c
  1067 --- pathexp.c.orig	2010-08-14 05:21:57.000000000 +0200
  1068 +++ pathexp.c	2012-06-27 10:31:02.000000000 +0200
  1069 @@ -196,7 +196,7 @@
  1071  	  if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
  1072  	    continue;
  1073 -	  if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
  1074 +	  if (pathname[i+1] != CTLESC && (qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
  1075  	    continue;
  1076  	  temp[j++] = '\\';
  1077  	  i++;
  1078 Index: print_cmd.c
  1079 --- print_cmd.c.orig	2010-05-31 00:34:08.000000000 +0200
  1080 +++ print_cmd.c	2012-06-27 10:31:02.000000000 +0200
  1081 @@ -315,6 +315,7 @@
  1082  	  cprintf ("( ");
  1083  	  skip_this_indent++;
  1084  	  make_command_string_internal (command->value.Subshell->command);
  1085 +	  PRINT_DEFERRED_HEREDOCS ("");
  1086  	  cprintf (" )");
  1087  	  break;
  1089 @@ -592,6 +593,7 @@
  1090    newline ("do\n");
  1091    indentation += indentation_amount;
  1092    make_command_string_internal (arith_for_command->action);
  1093 +  PRINT_DEFERRED_HEREDOCS ("");
  1094    semicolon ();
  1095    indentation -= indentation_amount;
  1096    newline ("done");
  1097 @@ -653,6 +655,7 @@
  1100    make_command_string_internal (group_command->command);
  1101 +  PRINT_DEFERRED_HEREDOCS ("");
  1103    if (inside_function_def)
  1105 Index: shell.h
  1106 --- shell.h.orig	2011-01-07 04:16:55.000000000 +0100
  1107 +++ shell.h	2012-06-27 10:31:02.000000000 +0200
  1108 @@ -136,6 +136,9 @@
  1109    int parser_state;
  1110    int *token_state;
  1112 +  char *token;
  1113 +  int token_buffer_size;
  1115    /* input line state -- line number saved elsewhere */
  1116    int input_line_terminator;
  1117    int eof_encountered;
  1118 @@ -166,6 +169,16 @@
  1120  } sh_parser_state_t;
  1122 +typedef struct _sh_input_line_state_t {
  1123 +  char *input_line;
  1124 +  int input_line_index;
  1125 +  int input_line_size;
  1126 +  int input_line_len;
  1127 +} sh_input_line_state_t;
  1129  /* Let's try declaring these here. */
  1130  extern sh_parser_state_t *save_parser_state __P((sh_parser_state_t *));
  1131  extern void restore_parser_state __P((sh_parser_state_t *));
  1133 +extern sh_input_line_state_t *save_input_line_state __P((sh_input_line_state_t *));
  1134 +extern void restore_input_line_state __P((sh_input_line_state_t *));
  1135 Index: sig.c
  1136 --- sig.c.orig	2010-11-23 14:21:22.000000000 +0100
  1137 +++ sig.c	2012-06-27 10:31:02.000000000 +0200
  1138 @@ -46,6 +46,7 @@
  1140  #if defined (READLINE)
  1141  #  include "bashline.h"
  1142 +#  include <readline/readline.h>
  1143  #endif
  1145  #if defined (HISTORY)
  1146 @@ -62,6 +63,7 @@
  1147  #if defined (HISTORY)
  1148  extern int history_lines_this_session;
  1149  #endif
  1150 +extern int no_line_editing;
  1152  extern void initialize_siglist ();
  1154 @@ -505,7 +507,10 @@
  1156  #if defined (HISTORY)
  1157        /* XXX - will inhibit history file being written */
  1158 -      history_lines_this_session = 0;
  1159 +#  if defined (READLINE)
  1160 +      if (interactive_shell == 0 || interactive == 0 || (sig != SIGHUP && sig != SIGTERM) || no_line_editing || (RL_ISSTATE (RL_STATE_READCMD) == 0))
  1161 +#  endif
  1162 +        history_lines_this_session = 0;
  1163  #endif
  1164        terminate_immediately = 0;
  1165        termsig_handler (sig);
  1166 Index: subst.c
  1167 --- subst.c.orig	2011-01-02 22:12:51.000000000 +0100
  1168 +++ subst.c	2012-06-27 10:31:03.000000000 +0200
  1169 @@ -366,6 +366,11 @@
  1170        f &= ~W_ASSNBLTIN;
  1171        fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
  1173 +  if (f & W_ASSNGLOBAL)
  1174 +    {
  1175 +      f &= ~W_ASSNGLOBAL;
  1176 +      fprintf (stderr, "W_ASSNGLOBAL%s", f ? "|" : "");
  1177 +    }
  1178    if (f & W_COMPASSIGN)
  1180        f &= ~W_COMPASSIGN;
  1181 @@ -1379,10 +1384,12 @@
  1182    slen = strlen (string + *sindex) + *sindex;
  1184    /* The handling of dolbrace_state needs to agree with the code in parse.y:
  1185 -     parse_matched_pair() */
  1186 -  dolbrace_state = 0;
  1187 -  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
  1188 -    dolbrace_state = (flags & SX_POSIXEXP) ? DOLBRACE_QUOTE : DOLBRACE_PARAM;
  1189 +     parse_matched_pair().  The different initial value is to handle the
  1190 +     case where this function is called to parse the word in
  1191 +     ${param op word} (SX_WORD). */
  1192 +  dolbrace_state = (flags & SX_WORD) ? DOLBRACE_WORD : DOLBRACE_PARAM;
  1193 +  if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && (flags & SX_POSIXEXP))
  1194 +    dolbrace_state = DOLBRACE_QUOTE;
  1196    i = *sindex;
  1197    while (c = string[i])
  1198 @@ -2801,7 +2808,7 @@
  1200    else if (assign_list)
  1202 -      if (word->flags & W_ASSIGNARG)
  1203 +      if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL) == 0)
  1204  	aflags |= ASS_MKLOCAL;
  1205        if (word->flags & W_ASSIGNASSOC)
  1206  	aflags |= ASS_MKASSOC;
  1207 @@ -3371,7 +3378,7 @@
  1208    if (string == 0 || *string == '\0')
  1209      return (WORD_LIST *)NULL;
  1211 -  td.flags = 0;
  1212 +  td.flags = W_NOSPLIT2;		/* no splitting, remove "" and '' */
  1213    td.word = string;
  1214    tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
  1215    return (tresult);
  1216 @@ -3704,7 +3711,10 @@
  1217  	    break;
  1219        else if (string[i] == CTLNUL)
  1220 -	i++;
  1221 +	{
  1222 +	  i++;
  1223 +	  continue;
  1224 +	}
  1226        prev_i = i;
  1227        ADVANCE_CHAR (string, slen, i);
  1228 @@ -4156,7 +4166,7 @@
  1229    simple = (wpat[0] != L'\\' && wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'[');
  1230  #if defined (EXTENDED_GLOB)
  1231    if (extended_glob)
  1232 -    simple |= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
  1233 +    simple &= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
  1234  #endif
  1236    /* If the pattern doesn't match anywhere in the string, go ahead and
  1237 @@ -4607,6 +4617,7 @@
  1238    if (ifs_firstc == 0)
  1239  #endif
  1240      word->flags |= W_NOSPLIT;
  1241 +  word->flags |= W_NOSPLIT2;
  1242    result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
  1243    expand_no_split_dollar_star = 0;
  1245 @@ -5798,6 +5809,16 @@
  1246  	 is the only expansion that creates more than one word. */
  1247        if (qdollaratp && ((hasdol && quoted) || l->next))
  1248  	*qdollaratp = 1;
  1249 +      /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
  1250 +	 a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the
  1251 +	 flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the
  1252 +	 expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
  1253 +	 (which is more paranoia than anything else), we need to return the
  1254 +	 quoted null string and set the flags to indicate it. */
  1255 +      if (l->next == 0 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL(temp) && QUOTED_NULL(l->word->word) && (l->word->flags & W_HASQUOTEDNULL))
  1256 +	{
  1257 +	  w->flags |= W_HASQUOTEDNULL;
  1258 +	}
  1259        dispose_words (l);
  1261    else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
  1262 @@ -7176,7 +7197,7 @@
  1264        /* Extract the contents of the ${ ... } expansion
  1265  	 according to the Posix.2 rules. */
  1266 -      value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#') ? SX_POSIXEXP : 0);
  1267 +      value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#' || c =='/' || c == '^' || c == ',' || c ==':') ? SX_POSIXEXP|SX_WORD : SX_WORD);
  1268        if (string[sindex] == RBRACE)
  1269  	sindex++;
  1270        else
  1271 @@ -7268,6 +7289,7 @@
  1272      default:
  1273      case '\0':
  1274      bad_substitution:
  1275 +      last_command_exit_value = EXECUTION_FAILURE;
  1276        report_error (_("%s: bad substitution"), string ? string : "??");
  1277        FREE (value);
  1278        FREE (temp);
  1279 Index: subst.h
  1280 --- subst.h.orig	2010-12-03 02:21:29.000000000 +0100
  1281 +++ subst.h	2012-06-27 10:31:02.000000000 +0200
  1282 @@ -56,6 +56,7 @@
  1283  #define SX_NOLONGJMP	0x0040	/* don't longjmp on fatal error */
  1284  #define SX_ARITHSUB	0x0080	/* extracting $(( ... )) (currently unused) */
  1285  #define SX_POSIXEXP	0x0100	/* extracting new Posix pattern removal expansions in extract_dollar_brace_string */
  1286 +#define SX_WORD		0x0200	/* extracting word in ${param op word} */
  1288  /* Remove backslashes which are quoting backquotes from STRING.  Modifies
  1289     STRING, and returns a pointer to it. */
  1290 Index: support/shobj-conf
  1291 --- support/shobj-conf.orig	2009-10-28 14:20:21.000000000 +0100
  1292 +++ support/shobj-conf	2012-06-27 10:31:02.000000000 +0200
  1293 @@ -157,7 +157,7 @@
  1294  	;;
  1296  # Darwin/MacOS X
  1297 -darwin[89]*|darwin10*)
  1298 +darwin[89]*|darwin1[012]*)
  1299  	SHOBJ_STATUS=supported
  1300  	SHLIB_STATUS=supported
  1302 @@ -186,7 +186,7 @@
  1303  	SHLIB_LIBSUFF='dylib'
  1305  	case "${host_os}" in
  1306 -	darwin[789]*|darwin10*)	SHOBJ_LDFLAGS=''
  1307 +	darwin[789]*|darwin1[012]*)	SHOBJ_LDFLAGS=''
  1308  			SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
  1309  			;;
  1310  	*)		SHOBJ_LDFLAGS='-dynamic'
  1311 Index: tests/shopt.right
  1312 --- tests/shopt.right.orig	2010-07-03 05:36:30.000000000 +0200
  1313 +++ tests/shopt.right	2012-06-27 10:31:03.000000000 +0200
  1314 @@ -12,6 +12,7 @@
  1315  shopt -u compat32
  1316  shopt -u compat40
  1317  shopt -u compat41
  1318 +shopt -u direxpand
  1319  shopt -u dirspell
  1320  shopt -u dotglob
  1321  shopt -u execfail
  1322 @@ -68,6 +69,7 @@
  1323  shopt -u compat32
  1324  shopt -u compat40
  1325  shopt -u compat41
  1326 +shopt -u direxpand
  1327  shopt -u dirspell
  1328  shopt -u dotglob
  1329  shopt -u execfail
  1330 @@ -101,6 +103,7 @@
  1331  compat32       	off
  1332  compat40       	off
  1333  compat41       	off
  1334 +direxpand      	off
  1335  dirspell       	off
  1336  dotglob        	off
  1337  execfail       	off
  1338 Index: variables.c
  1339 --- variables.c.orig	2011-01-25 02:07:48.000000000 +0100
  1340 +++ variables.c	2012-06-27 10:31:02.000000000 +0200
  1341 @@ -3653,6 +3653,22 @@
  1342    return n;
  1345 +int
  1346 +chkexport (name)
  1347 +     char *name;
  1348 +{
  1349 +  SHELL_VAR *v;
  1351 +  v = find_variable (name);
  1352 +  if (v && exported_p (v))
  1353 +    {
  1354 +      array_needs_making = 1;
  1355 +      maybe_make_export_env ();
  1356 +      return 1;
  1357 +    }
  1358 +  return 0;
  1359 +}
  1361  void
  1362  maybe_make_export_env ()
  1364 @@ -4214,7 +4230,7 @@
  1365    { "TEXTDOMAIN", sv_locale },
  1366    { "TEXTDOMAINDIR", sv_locale },
  1368 -#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
  1369 +#if defined (HAVE_TZSET)
  1370    { "TZ", sv_tz },
  1371  #endif
  1373 @@ -4558,12 +4574,13 @@
  1375  #endif /* HISTORY */
  1377 -#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
  1378 +#if defined (HAVE_TZSET)
  1379  void
  1380  sv_tz (name)
  1381       char *name;
  1383 -  tzset ();
  1384 +  if (chkexport (name))
  1385 +    tzset ();
  1387  #endif
  1389 Index: variables.h
  1390 --- variables.h.orig	2010-12-03 02:22:01.000000000 +0100
  1391 +++ variables.h	2012-06-27 10:31:02.000000000 +0200
  1392 @@ -313,6 +313,7 @@
  1394  extern void sort_variables __P((SHELL_VAR **));
  1396 +extern int chkexport __P((char *));
  1397  extern void maybe_make_export_env __P((void));
  1398  extern void update_export_env_inplace __P((char *, int, char *));
  1399  extern void put_command_name_into_env __P((char *));
  1400 Index: y.tab.c
  1401 --- y.tab.c.orig	2011-01-04 15:57:56.000000000 +0100
  1402 +++ y.tab.c	2012-06-27 10:31:03.000000000 +0200
  1403 @@ -4811,7 +4811,7 @@
  1404  	 We do this only if it is time to do so. Notice that only here
  1405  	 is the mail alarm reset; nothing takes place in check_mail ()
  1406  	 except the checking of mail.  Please don't change this. */
  1407 -      if (prompt_is_ps1 && time_to_check_mail ())
  1408 +      if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ())
  1410  	  check_mail ();
  1411  	  reset_mail_timer ();
  1412 @@ -6154,6 +6154,7 @@
  1413       int flags;
  1415    sh_parser_state_t ps;
  1416 +  sh_input_line_state_t ls;
  1417    int orig_ind, nc, sflags;
  1418    char *ret, *s, *ep, *ostring;
  1420 @@ -6161,10 +6162,12 @@
  1421    orig_ind = *indp;
  1422    ostring = string;
  1424 +/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/
  1425    sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
  1426    if (flags & SX_NOLONGJMP)
  1427      sflags |= SEVAL_NOLONGJMP;
  1428    save_parser_state (&ps);
  1429 +  save_input_line_state (&ls);
  1431    /*(*/
  1432    parser_state |= PST_CMDSUBST|PST_EOFTOKEN;	/* allow instant ')' */ /*(*/
  1433 @@ -6173,6 +6176,8 @@
  1435    restore_parser_state (&ps);
  1436    reset_parser ();
  1437 +  /* reset_parser clears shell_input_line and associated variables */
  1438 +  restore_input_line_state (&ls);
  1439    if (interactive)
  1440      token_to_read = 0;
  1442 @@ -7447,6 +7452,9 @@
  1443  	    case 'A':
  1444  	      /* Make the current time/date into a string. */
  1445  	      (void) time (&the_time);
  1446 +#if defined (HAVE_TZSET)
  1447 +	      sv_tz ("TZ");		/* XXX -- just make sure */
  1448 +#endif
  1449  	      tm = localtime (&the_time);
  1451  	      if (c == 'd')
  1452 @@ -8217,6 +8225,12 @@
  1453    ps->expand_aliases = expand_aliases;
  1454    ps->echo_input_at_read = echo_input_at_read;
  1456 +  ps->token = token;
  1457 +  ps->token_buffer_size = token_buffer_size;
  1458 +  /* Force reallocation on next call to read_token_word */
  1459 +  token = 0;
  1460 +  token_buffer_size = 0;
  1462    return (ps);
  1465 @@ -8258,6 +8272,42 @@
  1467    expand_aliases = ps->expand_aliases;
  1468    echo_input_at_read = ps->echo_input_at_read;
  1470 +  FREE (token);
  1471 +  token = ps->token;
  1472 +  token_buffer_size = ps->token_buffer_size;
  1473 +}
  1475 +sh_input_line_state_t *
  1476 +save_input_line_state (ls)
  1477 +     sh_input_line_state_t *ls;
  1478 +{
  1479 +  if (ls == 0)
  1480 +    ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
  1481 +  if (ls == 0)
  1482 +    return ((sh_input_line_state_t *)NULL);
  1484 +  ls->input_line = shell_input_line;
  1485 +  ls->input_line_size = shell_input_line_size;
  1486 +  ls->input_line_len = shell_input_line_len;
  1487 +  ls->input_line_index = shell_input_line_index;
  1489 +  /* force reallocation */
  1490 +  shell_input_line = 0;
  1491 +  shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
  1492 +}
  1494 +void
  1495 +restore_input_line_state (ls)
  1496 +     sh_input_line_state_t *ls;
  1497 +{
  1498 +  FREE (shell_input_line);
  1499 +  shell_input_line = ls->input_line;
  1500 +  shell_input_line_size = ls->input_line_size;
  1501 +  shell_input_line_len = ls->input_line_len;
  1502 +  shell_input_line_index = ls->input_line_index;
  1504 +  set_line_mbstate ();
  1507  /************************************************

mercurial