]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20200417 snapshot
authorChet Ramey <chet.ramey@case.edu>
Mon, 20 Apr 2020 14:11:53 +0000 (10:11 -0400)
committerChet Ramey <chet.ramey@case.edu>
Mon, 20 Apr 2020 14:11:53 +0000 (10:11 -0400)
20 files changed:
CWRU/CWRU.chlog
assoc.h
builtins/read.def
doc/bash.1
doc/bashref.texi
doc/version.texi
execute_cmd.c
hashcmd.h
jobs.c
jobs.h
nojobs.c
subst.c
tests/RUN-ONE-TEST
tests/appendop.right
tests/array.right
tests/assoc.right
tests/new-exp.right
tests/type.right
tests/varenv.right
variables.c

index 9e668be5c48f816cbf9e4b9ee7ece6de7285d528..9a51b0656e83efc296ab0ae9d796fe00983927b2 100644 (file)
@@ -8009,3 +8009,70 @@ examples/loadables/cut.c
        - lcut: new builtin that does what cut does but on a string supplied
          as an argument (only one string for now)
 
+                                  4/17
+                                  ----
+jobs.h
+       - FORK_SYNC,FORK_ASYNC,FORK_NOJOB: new flag values for the second
+         argument to make_child
+
+jobs.c
+       - make_child: now takes a set of flags as the second argument
+
+execute_cmd.c
+       - make_child: change callers to pass FORK_ASYNC instead of a non-zero
+         value as the second argument
+
+subst.c
+       - make_child: change callers to pass FORK_ASYNC instead of a non-zero
+         value as the second argument
+
+doc/{bash.1,bashref.texi}
+       - document that the words in a compound array assignment undergo all
+         the shell word expansions, including filename generation and word
+         splitting. From a report from E. Choroba <choroba@matfyz.cz>
+
+                                  4/18
+                                  ----
+subst.c
+       - command_substitute: use JOB_CONTROL instead of INTERACTIVE in the
+         test to determine whether or not to give the terminal back to
+         pipeline_pgrp
+
+jobs.c
+       - make_child: if FORK_NOTERM is set in the flags argument, don't call
+         give_terminal_to
+
+{jobs,nojobs}.c,jobs.h
+       - wait_for: now takes a second argument, a flags word
+
+{execute_cmd,subst}.c
+       - wait_for: change all callers to add second argument to wait_for
+
+jobs.c
+       - wait_for: if JWAIT_NOTERM is set in the flags argument, don't call
+         give_terminal_to
+
+                                  4/19
+                                  ----
+subst.c
+       - command_substitute: block SIGINT around call to read_comsub, so we
+         let any interrupts affect the command substitution. Fixes issue
+         reported by DALECKI Léo <leo.dalecki@ntymail.com>
+
+hashcmd.h
+       - FILENAME_HASH_BUCKETS: increase to 256
+
+assoc.h
+       - ASSOC_HASH_BUCKETS: new define, set to 1024
+
+variables.c
+       - make_new_assoc_variable,make_local_assoc_variable: call assoc_create
+         with ASSOC_HASH_BUCKETS as argument. This changes the hash function
+         and how the array keys are ordered (which is not guaranteed)
+
+builtins/read.def
+       - read_builtin: in posix mode, or if the read call returns -1/EINTR,
+         don't call run_pending_traps until the read command returns. This
+         allows a trap action to see the same exit status that the read
+         builtin would return when it exits on a signal (e.g., SIGINT == 130).
+         From a suggestion by <gentoo_eshoes@tutanota.com>
diff --git a/assoc.h b/assoc.h
index b5a263975f23cde46f4fa416068033f34dd0732c..78ec07386d0576d1f67c76648c3def445c2e0240 100644 (file)
--- a/assoc.h
+++ b/assoc.h
@@ -1,7 +1,7 @@
 /* assoc.h -- definitions for the interface exported by assoc.c that allows
    the rest of the shell to manipulate associative array variables. */
 
-/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
+/* Copyright (C) 2008,2009-2020 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -25,6 +25,8 @@
 #include "stdc.h"
 #include "hashlib.h"
 
+#define ASSOC_HASH_BUCKETS     1024
+
 #define assoc_empty(h)         ((h)->nentries == 0)
 #define assoc_num_elements(h)  ((h)->nentries)
 
 
 #define assoc_walk(h, f)       (hash_walk((h), (f))
 
-extern void assoc_dispose __P((HASH_TABLE *));
-extern void assoc_flush __P((HASH_TABLE *));
+extern void assoc_dispose PARAMS((HASH_TABLE *));
+extern void assoc_flush PARAMS((HASH_TABLE *));
 
-extern int assoc_insert __P((HASH_TABLE *, char *, char *));
-extern PTR_T assoc_replace __P((HASH_TABLE *, char *, char *));
-extern void assoc_remove __P((HASH_TABLE *, char *));
+extern int assoc_insert PARAMS((HASH_TABLE *, char *, char *));
+extern PTR_T assoc_replace PARAMS((HASH_TABLE *, char *, char *));
+extern void assoc_remove PARAMS((HASH_TABLE *, char *));
 
-extern char *assoc_reference __P((HASH_TABLE *, char *));
+extern char *assoc_reference PARAMS((HASH_TABLE *, char *));
 
-extern char *assoc_subrange __P((HASH_TABLE *, arrayind_t, arrayind_t, int, int, int));
-extern char *assoc_patsub __P((HASH_TABLE *, char *, char *, int));
-extern char *assoc_modcase __P((HASH_TABLE *, char *, int, int));
+extern char *assoc_subrange PARAMS((HASH_TABLE *, arrayind_t, arrayind_t, int, int, int));
+extern char *assoc_patsub PARAMS((HASH_TABLE *, char *, char *, int));
+extern char *assoc_modcase PARAMS((HASH_TABLE *, char *, int, int));
 
-extern HASH_TABLE *assoc_quote __P((HASH_TABLE *));
-extern HASH_TABLE *assoc_quote_escapes __P((HASH_TABLE *));
-extern HASH_TABLE *assoc_dequote __P((HASH_TABLE *));
-extern HASH_TABLE *assoc_dequote_escapes __P((HASH_TABLE *));
-extern HASH_TABLE *assoc_remove_quoted_nulls __P((HASH_TABLE *));
+extern HASH_TABLE *assoc_quote PARAMS((HASH_TABLE *));
+extern HASH_TABLE *assoc_quote_escapes PARAMS((HASH_TABLE *));
+extern HASH_TABLE *assoc_dequote PARAMS((HASH_TABLE *));
+extern HASH_TABLE *assoc_dequote_escapes PARAMS((HASH_TABLE *));
+extern HASH_TABLE *assoc_remove_quoted_nulls PARAMS((HASH_TABLE *));
 
-extern char *assoc_to_kvpair __P((HASH_TABLE *, int));
-extern char *assoc_to_assign __P((HASH_TABLE *, int));
+extern char *assoc_to_kvpair PARAMS((HASH_TABLE *, int));
+extern char *assoc_to_assign PARAMS((HASH_TABLE *, int));
 
-extern WORD_LIST *assoc_to_word_list __P((HASH_TABLE *));
-extern WORD_LIST *assoc_keys_to_word_list __P((HASH_TABLE *));
+extern WORD_LIST *assoc_to_word_list PARAMS((HASH_TABLE *));
+extern WORD_LIST *assoc_keys_to_word_list PARAMS((HASH_TABLE *));
 
-extern char *assoc_to_string __P((HASH_TABLE *, char *, int));
+extern char *assoc_to_string PARAMS((HASH_TABLE *, char *, int));
 #endif /* _ASSOC_H_ */
index 47715512c838f38edb81edb3735f40bf35d8dee3..18f0193074bcfbea398d0781c5dab64b48dcc3f8 100644 (file)
@@ -624,7 +624,9 @@ read_builtin (list)
              lastsig = LASTSIG();
              if (lastsig == 0)
                lastsig = trapped_signal_received;
+#if 0
              run_pending_traps ();     /* because interrupt_immediately is not set */
+#endif
            }
          else
            lastsig = 0;
index a2b659b55441a53f33a4080f65dc0b9111daf3b2..151c14cb5d10a1cd55c10ab07b41d31403bbbc63 100644 (file)
@@ -5,12 +5,12 @@
 .\"    Case Western Reserve University
 .\"    chet.ramey@case.edu
 .\"
-.\"    Last Change: Thu Apr  9 11:50:30 EDT 2020
+.\"    Last Change: Fri Apr 17 16:30:01 EDT 2020
 .\"
 .\" bash_builtins, strip all but Built-Ins section
 .if \n(zZ=1 .ig zZ
 .if \n(zY=1 .ig zY
-.TH BASH 1 "2020 April 9" "GNU Bash 5.0"
+.TH BASH 1 "2020 April 17" "GNU Bash 5.0"
 .\"
 .\" There's some problem with having a `@'
 .\" in a tagged paragraph with the BSD man macros.
@@ -2682,6 +2682,10 @@ Arrays are assigned to using compound assignments of the form
 \fIname\fP=\fB(\fPvalue\fI1\fP ... value\fIn\fP\fB)\fP, where each
 \fIvalue\fP may be of the form [\fIsubscript\fP]=\fIstring\fP.
 Indexed array assignments do not require anything but \fIstring\fP.
+Each \fIvalue\fP in the list is expanded using all the shell expansions
+described below under
+.SM
+.BR EXPANSION .
 When assigning to indexed arrays, if the optional brackets and subscript
 are supplied, that index is assigned to;
 otherwise the index of the element assigned is the last index assigned
index 4a57871a8fca1e2dc3891a614fa78fd6dc023557..4c1111a185adcdf01edb15f8a33a087435a458a8 100644 (file)
@@ -7312,6 +7312,9 @@ the optional subscript is supplied, that index is assigned to;
 otherwise the index of the element assigned is the last index assigned
 to by the statement plus one.  Indexing starts at zero.
 
+Each @var{value} in the list undergoes all the shell expansions
+described above (@pxref{Shell Expansions}).
+
 When assigning to an associative array, the words in a compound assignment
 may be either assignment statements, for which the subscript is required,
 or a list of words that is interpreted as a sequence of alternating keys
index 3098b9c7428d88cd77c2ee9def8f90f2f486d6c0..cfbd58c8e24db7cd5532fcd22c5f39ad8bdeb225 100644 (file)
@@ -2,10 +2,10 @@
 Copyright (C) 1988-2020 Free Software Foundation, Inc.
 @end ignore
 
-@set LASTCHANGE Thu Apr  9 11:58:06 EDT 2020
+@set LASTCHANGE Fri Apr 17 16:30:16 EDT 2020
 
 @set EDITION 5.0
 @set VERSION 5.0
 
-@set UPDATED 9 April 2020
+@set UPDATED 17 April 2020
 @set UPDATED-MONTH April 2020
index 3b40e8066d2494ae09adbbf0c47b9b866288ffbb..6e27f5c1b81c5b3727f4a39b218387076014306b 100644 (file)
@@ -556,7 +556,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
      int pipe_in, pipe_out;
      struct fd_bitmap *fds_to_close;
 {
-  int exec_result, user_subshell, invert, ignore_return, was_error_trap;
+  int exec_result, user_subshell, invert, ignore_return, was_error_trap, fork_flags;
   REDIRECT *my_undo_list, *exec_undo_list;
   char *tcmd;
   volatile int save_line_number;
@@ -627,7 +627,8 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
        line_number_for_err_trap = line_number = command->value.Subshell->line; /* XXX - save value? */
        /* Otherwise we defer setting line_number */
       tcmd = make_command_string (command);
-      paren_pid = make_child (p = savestring (tcmd), asynchronous);
+      fork_flags = asynchronous ? FORK_ASYNC : 0;
+      paren_pid = make_child (p = savestring (tcmd), fork_flags);
 
       if (user_subshell && signal_is_trapped (ERROR_TRAP) && 
          signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
@@ -684,7 +685,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
              invert = (command->flags & CMD_INVERT_RETURN) != 0;
              ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
 
-             exec_result = wait_for (paren_pid);
+             exec_result = wait_for (paren_pid, 0);
 
              /* If we have to, invert the return value. */
              if (invert)
@@ -865,7 +866,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
               the function to be waited for twice.  This also causes
               subshells forked to execute builtin commands (e.g., in
               pipelines) to be waited for twice. */
-             exec_result = wait_for (last_made_pid);
+             exec_result = wait_for (last_made_pid, 0);
          }
       }
 
@@ -1103,10 +1104,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
 
   last_command_exit_value = exec_result;
   run_pending_traps ();
-#if 0
-  if (running_trap == 0)
-#endif
-    currently_executing_command = (COMMAND *)NULL;
+  currently_executing_command = (COMMAND *)NULL;
 
   return (last_command_exit_value);
 }
@@ -2367,7 +2365,7 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
 
   BLOCK_SIGNAL (SIGCHLD, set, oset);
 
-  coproc_pid = make_child (p = savestring (tcmd), 1);
+  coproc_pid = make_child (p = savestring (tcmd), FORK_ASYNC);
 
   if (coproc_pid == 0)
     {
@@ -2590,12 +2588,12 @@ execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close)
       if (INVALID_JOB (lastpipe_jid) == 0)
         {
           append_process (savestring (the_printed_command_except_trap), dollar_dollar_pid, exec_result, lastpipe_jid);
-          lstdin = wait_for (lastpid);
+          lstdin = wait_for (lastpid, 0);
         }
       else
         lstdin = wait_for_single_pid (lastpid, 0);             /* checks bgpids list */
 #else
-      lstdin = wait_for (lastpid);
+      lstdin = wait_for (lastpid, 0);
 #endif
 
 #if defined (JOB_CONTROL)
@@ -3986,7 +3984,7 @@ execute_null_command (redirects, pipe_in, pipe_out, async)
      int pipe_in, pipe_out, async;
 {
   int r;
-  int forcefork;
+  int forcefork, fork_flags;
   REDIRECT *rd;
 
   for (forcefork = 0, rd = redirects; rd; rd = rd->next)
@@ -4000,7 +3998,8 @@ execute_null_command (redirects, pipe_in, pipe_out, async)
     {
       /* We have a null command, but we really want a subshell to take
         care of it.  Just fork, do piping and redirections, and exit. */
-      if (make_child ((char *)NULL, async) == 0)
+      fork_flags = async ? FORK_ASYNC : 0;
+      if (make_child ((char *)NULL, fork_flags) == 0)
        {
          /* Cancel traps, in trap.c. */
          restore_original_signals ();          /* XXX */
@@ -4168,6 +4167,7 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
   WORD_LIST *words, *lastword;
   char *command_line, *lastarg, *temp;
   int first_word_quoted, result, builtin_is_special, already_forked, dofork;
+  int fork_flags;
   pid_t old_last_async_pid;
   sh_builtin_func_t *builtin;
   SHELL_VAR *func;
@@ -4244,7 +4244,8 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
 
       /* Don't let a DEBUG trap overwrite the command string to be saved with
         the process/job associated with this child. */
-      if (make_child (p = savestring (the_printed_command_except_trap), async) == 0)
+      fork_flags = async ? FORK_ASYNC : 0;
+      if (make_child (p = savestring (the_printed_command_except_trap), fork_flags) == 0)
        {
          already_forked = 1;
          simple_command->flags |= CMD_NO_FORK;
@@ -5331,7 +5332,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
      int cmdflags;
 {
   char *pathname, *command, **args, *p;
-  int nofork, stdpath, result;
+  int nofork, stdpath, result, fork_flags;
   pid_t pid;
   SHELL_VAR *hookf;
   WORD_LIST *wl;
@@ -5380,7 +5381,10 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
   if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE)
     pid = 0;
   else
-    pid = make_child (p = savestring (command_line), async);
+    {
+      fork_flags = async ? FORK_ASYNC : 0;
+      pid = make_child (p = savestring (command_line), fork_flags);
+    }
 
   if (pid == 0)
     {
index 758f5b4b9fdb3d795ec40186293816d9b7d7760b..2459f200414c45499311556853dcfdc29afd994e 100644 (file)
--- a/hashcmd.h
+++ b/hashcmd.h
@@ -1,6 +1,6 @@
 /* hashcmd.h - Common defines for hashing filenames. */
 
-/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1993-2020 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -21,7 +21,7 @@
 #include "stdc.h"
 #include "hashlib.h"
 
-#define FILENAME_HASH_BUCKETS 64       /* must be power of two */
+#define FILENAME_HASH_BUCKETS 256      /* must be power of two */
 
 extern HASH_TABLE *hashed_filenames;
 
@@ -35,9 +35,9 @@ typedef struct _pathdata {
 
 #define pathdata(x) ((PATH_DATA *)(x)->data)
 
-extern void phash_create __P((void));
-extern void phash_flush __P((void));
+extern void phash_create PARAMS((void));
+extern void phash_flush PARAMS((void));
 
-extern void phash_insert __P((char *, char *, int, int));
-extern int phash_remove __P((const char *));
-extern char *phash_search __P((const char *));
+extern void phash_insert PARAMS((char *, char *, int, int));
+extern int phash_remove PARAMS((const char *));
+extern char *phash_search PARAMS((const char *));
diff --git a/jobs.c b/jobs.c
index 95e68efce59022591351ea4fb4832f6e18952410..b791900de8933609a1d9f41edaeaa65c9a549a9a 100644 (file)
--- a/jobs.c
+++ b/jobs.c
@@ -1079,7 +1079,7 @@ procsub_waitpid (pid)
     return -1;
   if (p->running == PS_DONE)
     return (p->status);
-  r = wait_for (p->pid);
+  r = wait_for (p->pid, 0);
   return (r);                  /* defer removing until later */
 }
 
@@ -1093,7 +1093,7 @@ procsub_waitall ()
     {
       if (p->running == PS_DONE)
        continue;
-      r = wait_for (p->pid);
+      r = wait_for (p->pid, 0);
     }
 }
 
@@ -2252,7 +2252,7 @@ make_child (command, flags)
             In this case, we don't want to give the terminal to the
             shell's process group (we could be in the middle of a
             pipeline, for example). */
-         if (async_p == 0 && pipeline_pgrp != shell_pgrp && ((subshell_environment&(SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0) && running_in_background == 0)
+         if ((flags & FORK_NOTERM) == 0 && async_p == 0 && pipeline_pgrp != shell_pgrp && ((subshell_environment&(SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0) && running_in_background == 0)
            give_terminal_to (pipeline_pgrp, 0);
 
 #if defined (PGRP_PIPE)
@@ -2609,7 +2609,7 @@ wait_for_single_pid (pid, flags)
   alive = 0;
   do
     {
-      r = wait_for (pid);
+      r = wait_for (pid, 0);
       if ((flags & JWAIT_FORCE) == 0)
        break;
 
@@ -2899,8 +2899,9 @@ job_exit_signal (job)
    the jobs table.  Returns -1 if waitchld() returns -1, indicating
    that there are no unwaited-for child processes. */
 int
-wait_for (pid)
+wait_for (pid, flags)
      pid_t pid;
+     int flags;
 {
   int job, termination_state, r;
   WAIT s;
@@ -3235,7 +3236,7 @@ wait_for_job (job, flags, ps)
 
   do
     {
-      r = wait_for (pid);
+      r = wait_for (pid, 0);
       if (r == -1 && errno == ECHILD)
        mark_all_jobs_as_dead ();
 
@@ -3331,7 +3332,7 @@ return_job:
       CHECK_WAIT_INTR;
 
       errno = 0;
-      r = wait_for (ANY_PID);  /* special sentinel value for wait_for */
+      r = wait_for (ANY_PID, 0);       /* special sentinel value for wait_for */
       if (r == -1 && errno == ECHILD)
        mark_all_jobs_as_dead ();
        
@@ -3642,7 +3643,7 @@ start_job (job, foreground)
 
       pid = find_last_pid (job, 0);
       UNBLOCK_CHILD (oset);
-      st = wait_for (pid);
+      st = wait_for (pid, 0);
       shell_tty_info = save_stty;
       set_tty_state ();
       return (st);
diff --git a/jobs.h b/jobs.h
index f89669a5edd21c31156affe5f9ffad761684ad61..43ba8c23b291623230a5230e0ba55ee73ac78522 100644 (file)
--- a/jobs.h
+++ b/jobs.h
 /* I looked it up.  For pretty_print_job ().  The real answer is 24. */
 #define LONGEST_SIGNAL_DESC 24
 
-/* Defines for the wait_for functions and for the wait builtin to use */
-#define JWAIT_PERROR           0x01
-#define JWAIT_FORCE            0x02 
-#define JWAIT_NOWAIT           0x04    /* don't waitpid(), just return status if already exited */
-#define JWAIT_WAITING          0x08    /* wait for jobs marked J_WAITING only */
+/* Defines for the wait_for_* functions and for the wait builtin to use */
+#define JWAIT_PERROR           (1 << 0)
+#define JWAIT_FORCE            (1 << 1)
+#define JWAIT_NOWAIT           (1 << 2) /* don't waitpid(), just return status if already exited */
+#define JWAIT_WAITING          (1 << 3) /* wait for jobs marked J_WAITING only */
+
+/* flags for wait_for */
+#define JWAIT_NOTERM           (1 << 8) /* wait_for doesn't give terminal away */
 
 /* The max time to sleep while retrying fork() on EAGAIN failure */
 #define FORKSLEEP_MAX  16
@@ -197,9 +200,10 @@ struct procchain {
 #define ANY_PID (pid_t)-1
 
 /* flags for make_child () */
-#define FORK_SYNC      0
-#define FORK_ASYNC     1
-#define FORK_NOJOB     2
+#define FORK_SYNC      0               /* normal synchronous process */
+#define FORK_ASYNC     1               /* background process */
+#define FORK_NOJOB     2               /* don't put process in separate pgrp */
+#define FORK_NOTERM    4               /* don't give terminal to any pgrp */
 
 /* System calls. */
 #if !defined (HAVE_UNISTD_H)
@@ -276,7 +280,7 @@ extern int job_exit_signal PARAMS((int));
 
 extern int wait_for_single_pid PARAMS((pid_t, int));
 extern void wait_for_background_pids PARAMS((struct procstat *));
-extern int wait_for PARAMS((pid_t));
+extern int wait_for PARAMS((pid_t, int));
 extern int wait_for_job PARAMS((int, int, struct procstat *));
 extern int wait_for_any_job PARAMS((int, struct procstat *));
 
index b7b64d171d45d393db1f8017120230ff6ef11132..89c09b3d4a84caaa55918893bc910fdc269b9218 100644 (file)
--- a/nojobs.c
+++ b/nojobs.c
@@ -823,8 +823,9 @@ j_strsignal (s)
 /* Wait for pid (one of our children) to terminate.  This is called only
    by the execution code in execute_cmd.c. */
 int
-wait_for (pid)
+wait_for (pid, flags)
      pid_t pid;
+     int flags;
 {
   int return_val, pstatus;
   pid_t got_pid;
diff --git a/subst.c b/subst.c
index 1ffd618ca8f9811bf7d686376f7c598671b15b12..1d91dd5d0ee8e6f62da738bff9207eea79a35576 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -5555,7 +5555,7 @@ wait_procsubs ()
     {
       if (fifo_list[i].proc != (pid_t)-1 && fifo_list[i].proc > 0)
        {
-         r = wait_for (fifo_list[i].proc);
+         r = wait_for (fifo_list[i].proc, 0);
          save_proc_status (fifo_list[i].proc, r);
          fifo_list[i].proc = (pid_t)-1;
        }
@@ -5793,7 +5793,7 @@ wait_procsubs ()
     {
       if (dev_fd_list[i] != (pid_t)-1 && dev_fd_list[i] > 0)
        {
-         r = wait_for (dev_fd_list[i]);
+         r = wait_for (dev_fd_list[i], 0);
          save_proc_status (dev_fd_list[i], r);
          dev_fd_list[i] = (pid_t)-1;
        }
@@ -5901,7 +5901,7 @@ process_substitute (string, open_for_read_in_child)
   save_pipeline (1);
 #endif /* JOB_CONTROL */
 
-  pid = make_child ((char *)NULL, 1);
+  pid = make_child ((char *)NULL, FORK_ASYNC);
   if (pid == 0)
     {
 interactive = 0;
@@ -6141,8 +6141,7 @@ read_comsub (fd, quoted, flags, rflag)
   mb_cur_max = MB_CUR_MAX;
   nullbyte = 0;
 
-  /* Read the output of the command through the pipe.  This may need to be
-     changed to understand multibyte characters in the future. */
+  /* Read the output of the command through the pipe. */
   while (1)
     {
       if (fd < 0)
@@ -6206,16 +6205,6 @@ read_comsub (fd, quoted, flags, rflag)
 #endif
 
       istring[istring_index++] = c;
-
-#if 0
-#if defined (__CYGWIN__)
-      if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
-       {
-         istring_index--;
-         istring[istring_index - 1] = '\n';
-       }
-#endif
-#endif
     }
 
   if (istring)
@@ -6267,8 +6256,9 @@ command_substitute (string, quoted, flags)
 {
   pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
   char *istring, *s;
-  int result, fildes[2], function_value, pflags, rc, tflag;
+  int result, fildes[2], function_value, pflags, rc, tflag, fork_flags;
   WORD_DESC *ret;
+  sigset_t set, oset;
 
   istring = (char *)NULL;
 
@@ -6323,7 +6313,8 @@ command_substitute (string, quoted, flags)
 #endif /* JOB_CONTROL */
 
   old_async_pid = last_asynchronous_pid;
-  pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
+  fork_flags = (subshell_environment&SUBSHELL_ASYNC) ? FORK_ASYNC : 0;
+  pid = make_child ((char *)NULL, fork_flags);
   last_asynchronous_pid = old_async_pid;
 
   if (pid == 0)
@@ -6486,14 +6477,19 @@ command_substitute (string, quoted, flags)
       dummyfd = fildes[0];
       add_unwind_protect (close, dummyfd);
 
+      /* Block SIGINT while we're reading from the pipe. If the child
+        process gets a SIGINT, it will either handle it or die, and the
+        read will return. */
+      BLOCK_SIGNAL (SIGINT, set, oset);
       tflag = 0;
       istring = read_comsub (fildes[0], quoted, flags, &tflag);
 
       close (fildes[0]);
       discard_unwind_frame ("read-comsub");
+      UNBLOCK_SIGNAL (oset);
 
       current_command_subst_pid = pid;
-      last_command_exit_value = wait_for (pid);
+      last_command_exit_value = wait_for (pid, 0);
       last_command_subst_pid = pid;
       last_made_pid = old_pid;
 
index 0b06381072414283266cf5d055a42ac14b9b6da6..c8bef8dd12533217b1b65fc20d00f3d1cc1b81e7 100755 (executable)
@@ -1,4 +1,4 @@
-BUILD_DIR=/usr/local/build/chet/bash/bash-current
+BUILD_DIR=/usr/local/build/bash/bash-current
 THIS_SH=$BUILD_DIR/bash
 PATH=$PATH:$BUILD_DIR
 
index dcb60b0b51df7bbf42983335a3de84e950075c98..f72696b17825f2161e3728c51f10ac6d51a930e8 100644 (file)
@@ -17,8 +17,8 @@
 16
 ./appendop.tests: line 97: x: readonly variable
 declare -A foo=([two]="baz" [three]="quux" [one]="bar" )
-declare -A foo=([two]="baz" [0]="zero" [three]="quux" [one]="bar" )
-declare -A foo=([two]="baz" [0]="zero" [three]="quux" [four]="four" [one]="bar" )
+declare -A foo=([0]="zero" [two]="baz" [three]="quux" [one]="bar" )
+declare -A foo=([four]="four" [0]="zero" [two]="baz" [three]="quux" [one]="bar" )
 declare -ai iarr=([0]="3" [1]="2" [2]="3")
 declare -ai iarr=([0]="3" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6")
 25 25
index afc03bc8616252bd3cf0b40d62f0334e132e4d9d..c46ffb5eb010558cb4a32bc1232c41cb9966b5a8 100644 (file)
@@ -349,10 +349,10 @@ version[agent]
 version.agent
 version[agent]
 version.agent
-version[agent] foo[bar]
-version.agent bowl
-foo foobar] foo[bar]
-bbb bleh bleh
+foo[bar] version[agent]
+bowl version.agent
+foobar] foo foo[bar]
+bleh bbb bleh
 ab]
 bar
 1
index 200362543da59807f027e158e763eff6e404e6d1..e1e45fcbc20c053d8edbf9169fdf1c59b44bb168 100644 (file)
@@ -6,14 +6,14 @@ declare -A BASH_CMDS=()
 declare -A fluff=([foo]="one" [bar]="two" )
 declare -A fluff=([foo]="one" [bar]="two" )
 declare -A fluff=([bar]="two" )
-declare -A fluff=([bar]="newval" [qux]="assigned" )
+declare -A fluff=([qux]="assigned" [bar]="newval" )
 ./assoc.tests: line 39: chaff: four: must use subscript when assigning associative array
 declare -A BASH_ALIASES=()
 declare -A BASH_CMDS=()
-declare -Ai chaff=([zero]="5" [one]="10" )
-declare -Ar waste=([lineno]="41" [source]="./assoc.tests" [version]="4.0-devel" [pid]="42134" )
-declare -A wheat=([two]="b" [three]="c" [zero]="0" [one]="a" )
-declare -A chaff=(["hello world"]="flip" [zero]="5" [one]="10" )
+declare -Ai chaff=([one]="10" [zero]="5" )
+declare -Ar waste=([pid]="42134" [lineno]="41" [source]="./assoc.tests" [version]="4.0-devel" )
+declare -A wheat=([two]="b" [three]="c" [one]="a" [zero]="0" )
+declare -A chaff=(["hello world"]="flip" [one]="10" [zero]="5" )
 ./assoc.tests: line 51: waste: readonly variable
 ./assoc.tests: line 52: unset: waste: cannot unset: readonly variable
 ./assoc.tests: line 53: chaff[*]: bad array subscript
@@ -35,11 +35,11 @@ argv[1] = <multiple words flip a>
 ./assoc.tests: line 71: declare: chaff: cannot destroy array variables in this way
 ./assoc.tests: line 73: chaff[*]: bad array subscript
 ./assoc.tests: line 74: [*]=12: invalid associative array key
-declare -A wheat=(["foo bar"]="qux qix" [six]="6" )
+declare -A wheat=([six]="6" ["foo bar"]="qux qix" )
 argv[1] = <qux>
 argv[2] = <qix>
 argv[1] = <qux qix>
-declare -A wheat=(["foo bar"]="qux qix" [six]="6" )
+declare -A wheat=([six]="6" ["foo bar"]="qux qix" )
 argv[1] = <2>
 argv[1] = <7>
 argv[1] = <qux>
@@ -48,16 +48,16 @@ argv[3] = <blat>
 argv[1] = <qux qix blat>
 argv[1] = <16>
 argv[1] = <16>
-argv[1] = <flix>
-argv[2] = <6>
-argv[1] = <foo>
-argv[2] = <bar>
-argv[3] = <six>
-argv[1] = <foo bar>
-argv[2] = <six>
+argv[1] = <6>
+argv[2] = <flix>
+argv[1] = <six>
+argv[2] = <foo>
+argv[3] = <bar>
+argv[1] = <six>
+argv[2] = <foo bar>
 8
-/sbin /usr/bin /bin /usr/ucb /usr/local/bin . /usr/sbin /bin
-sbin bin bin ucb bin . sbin bin
+/usr/local/bin /bin . /usr/bin /usr/ucb /usr/sbin /bin /sbin
+bin bin . bin ucb sbin bin sbin
 bin
 / / / / / / /
 /
@@ -66,27 +66,27 @@ argv[1] = </>
 argv[1] = <sbin>
 argv[1] = </>
 8
-/sbin /usr/bin /bin /usr/ucb /usr/local/bin . /usr/sbin /bin
-sbin bin bin ucb bin . sbin bin
+/usr/local/bin /bin . /usr/bin /usr/ucb /usr/sbin /bin /sbin
+bin bin . bin ucb sbin bin sbin
 / / / / / / /
 8
 4 -- /bin
-^sbin ^usr^bin ^bin ^usr^ucb ^usr^local^bin . ^usr^sbin ^bin
-^sbin ^usr^bin ^bin ^usr^ucb ^usr^local^bin . ^usr^sbin ^bin
-\sbin \usr/bin \bin \usr/ucb \usr/local/bin . \usr/sbin \bin
-\sbin \usr\bin \bin \usr\ucb \usr\local\bin . \usr\sbin \bin
-\sbin \usr\bin \bin \usr\ucb \usr\local\bin . \usr\sbin \bin
+^usr^local^bin ^bin . ^usr^bin ^usr^ucb ^usr^sbin ^bin ^sbin
+^usr^local^bin ^bin . ^usr^bin ^usr^ucb ^usr^sbin ^bin ^sbin
+\usr/local/bin \bin . \usr/bin \usr/ucb \usr/sbin \bin \sbin
+\usr\local\bin \bin . \usr\bin \usr\ucb \usr\sbin \bin \sbin
+\usr\local\bin \bin . \usr\bin \usr\ucb \usr\sbin \bin \sbin
 ([a]=1)
 
 foo qux
 /usr/sbin/foo /usr/local/bin/qux
 hits   command
-   0   /sbin/blat
    0   /usr/sbin/foo
    0   /bin/sh
+   0   /sbin/blat
    0   /usr/local/bin/qux
-blat foo sh qux
-/sbin/blat /usr/sbin/foo /bin/sh /usr/local/bin/qux
+foo sh blat qux
+/usr/sbin/foo /bin/sh /sbin/blat /usr/local/bin/qux
 
 foo qux
 argv[1] = </usr/sbin/foo>
@@ -104,10 +104,10 @@ argv[4] = </usr/local/bin/qux -l>
 outside: outside
 declare -A BASH_ALIASES=()
 declare -A BASH_CMDS=()
-declare -A afoo=(["foo bar"]="foo quux" [six]="six" )
+declare -A afoo=([six]="six" ["foo bar"]="foo quux" )
 argv[1] = <inside:>
-argv[2] = <foo quux>
-argv[3] = <six>
+argv[2] = <six>
+argv[3] = <foo quux>
 outside 2: outside
 argv[1] = </barq//fooq>
 argv[1] = <>
@@ -138,11 +138,11 @@ abc
 def
 def
 ./assoc5.sub: line 26: declare: `myarray[foo[bar]=bleh': not a valid identifier
-bleh def abc
-myarray=([foo]="bleh" ["]"]="def" ["a]=test1;#a"]="123" ["a]a"]="abc" )
+def bleh abc
+myarray=(["]"]="def" [foo]="bleh" ["a]a"]="abc" ["a]=test1;#a"]="123" )
 
 123
-myarray=([foo]="bleh" ["]"]="def" ["a]=test2;#a"]="def" ["a]=test1;#a"]="123" ["a]a"]="abc" )
+myarray=(["]"]="def" ["a]=test2;#a"]="def" [foo]="bleh" ["a]a"]="abc" ["a]=test1;#a"]="123" )
 bar"bie
 doll
 declare -A foo=(["bar\"bie"]="doll" )
@@ -234,11 +234,11 @@ main: declare -- a="42"
 declare -A a=([3]="" [1]="2" )
 declare -A foo=([d]="4" [c]="3" [b]="2" [a]="1" )
 foo=( d "4" c "3" b "2" a "1" )
-declare -A foo=(["spa ces"]="2" ["\\"]="5" ["@"]="3" ["holy hell this works"]="4" ["a b"]="1" )
-foo=( echo "spa ces" "2" "\\" "5" "@" "3" "holy hell this works" "4" "a b" "1" )
+declare -A foo=(["\\"]="5" ["@"]="3" ["holy hell this works"]="4" ["a b"]="1" ["spa ces"]="2" )
+foo=( echo "\\" "5" "@" "3" "holy hell this works" "4" "a b" "1" "spa ces" "2" )
 ./assoc11.sub: line 34: "": bad array subscript
-declare -A foo=(["foo[bar"]="bleh" [";"]="semicolon" ["]"]="def" [a=b]="assignment" ["a]a"]="abc" )
-foo=( "foo[bar" "bleh" ";" "semicolon" "]" "def" a=b "assignment" "a]a" "abc" )
+declare -A foo=([";"]="semicolon" ["]"]="def" [a=b]="assignment" ["a]a"]="abc" ["foo[bar"]="bleh" )
+foo=( ";" "semicolon" "]" "def" a=b "assignment" "a]a" "abc" "foo[bar" "bleh" )
 declare -A foo=(["'"]="squote" ["\""]="dquote" ["\\"]="bslash" ["\`"]="backquote" )
 foo=( "'" "squote" "\"" "dquote" "\\" "bslash" "\`" "backquote" )
 declare -A foo=(["bar]bie"]="doll" ["a]=test1;#a"]="123" ["bar\"bie"]="doll" )
index 2a1e05d958a29912f2c523d09270180a12cb853a..307a91859a9c24efe8c3a449591e5eac749b51ff 100644 (file)
@@ -635,7 +635,7 @@ declare -r x='ab '\''cd'\'' ef'
 set -- 'ab' 'cd ef' '' 'gh' 
 declare -a A=([0]="ab" [1]="cd ef" [2]="" [3]="gh") 
 declare -a B=() 
-declare -A A=([two]="b c" [three]="" [four]="de" [one]="1" ) 
+declare -A A=([four]="de" [two]="b c" [three]="" [one]="1" ) 
 r
 a 
 A 
index 76ce22953477e2bf88505b093f7feca2f46e6963..f876715a048ec6e977012bf3c4820aca9ce7ce53 100644 (file)
@@ -44,8 +44,8 @@ builtin is a shell builtin
 bash is hashed (/tmp/bash)
 file
 hits   command
-   3   /tmp/bash
    1   /bin/sh
+   3   /tmp/bash
 f is a function
 f () 
 { 
index 4c8ef2204b89bb477ce5234ad527ce719ee0d160..b16b4033fd169302ed54fc5994417a8ca055cba3 100644 (file)
@@ -133,7 +133,7 @@ after func: x = outside
 ./varenv11.sub: line 18: qux: readonly variable
 declare -A foo=([zero]="zero" [one]="one" )
 declare -a bar=([0]="zero" [1]="one")
-declare -A foo=([zero]="zero" [one]="one" )
+declare -A foo=([one]="one" [zero]="zero" )
 declare -a bar=([0]="zero" [1]="one")
 ./varenv11.sub: line 42: a: readonly variable
 foo=abc
index aacc12fa4c7566aeece09d61d92a0029c0d6020d..b06b606f519b6274defa3c1b61e7d70a5ffc33c3 100644 (file)
@@ -3015,7 +3015,7 @@ make_new_assoc_variable (name)
   HASH_TABLE *hash;
 
   entry = make_new_variable (name, global_variables->table);
-  hash = assoc_create (0);
+  hash = assoc_create (ASSOC_HASH_BUCKETS);
 
   var_setassoc (entry, hash);
   VSETATTR (entry, att_assoc);
@@ -3047,7 +3047,7 @@ make_local_assoc_variable (name, flags)
       internal_warning ("%s: cannot inherit value from incompatible type", name);
       VUNSETATTR (var, att_array);
       dispose_variable_value (var);
-      hash = assoc_create (0);
+      hash = assoc_create (ASSOC_HASH_BUCKETS);
       var_setassoc (var, hash);
     }
   else if (localvar_inherit)
@@ -3055,7 +3055,7 @@ make_local_assoc_variable (name, flags)
   else
     {
       dispose_variable_value (var);
-      hash = assoc_create (0);
+      hash = assoc_create (ASSOC_HASH_BUCKETS);
       var_setassoc (var, hash);
     }