]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20180817 snapshot
authorChet Ramey <chet.ramey@case.edu>
Mon, 20 Aug 2018 21:03:01 +0000 (17:03 -0400)
committerChet Ramey <chet.ramey@case.edu>
Mon, 20 Aug 2018 21:03:01 +0000 (17:03 -0400)
17 files changed:
CWRU/CWRU.chlog
MANIFEST
aclocal.m4
arrayfunc.c
configure
doc/bash.1
doc/bashref.texi
execute_cmd.c
jobs.c
jobs.h
lib/sh/snprintf.c
nojobs.c
tests/varenv.right
tests/varenv.tests
tests/varenv15.in [new file with mode: 0644]
tests/varenv15.sub [new file with mode: 0644]
variables.c

index 81082497d6f70064f765180d03c58ff3c69308d3..59f93ba93455df50952993890f0268c6dd0cc5e2 100644 (file)
@@ -3229,7 +3229,7 @@ doc/{bash.1,bashref.texi}
                                    2/1
                                    ---
 config-top.h
-       - DONT_REPORT_SIGPIPE: define, so non-interactive shells will no
+       - DONT_REPORT_SIGTERM: define, so non-interactive shells will no
          longer print termination messages for child processes killed by
          SIGTERM
 
@@ -4186,3 +4186,54 @@ builtins/declare.def
 configure.ac
        - globasciiranges: RRI now on by default, must be turned off explicitly
          at configure time or runtime with `shopt -u globasciiranges'
+
+                                  8/14
+                                  ----
+variables.c
+       - dispose_saved_dollar_vars: decrement stack pointer before looking
+         for saved positional parameters to dispose; stack pointer always
+         points to the first unused slot
+
+                                  8/15
+                                  ----
+variables.c
+       - dollar_arg_stack: now a stack of struct saved_dollar_vars, which has
+         an array for the first ten (dollar_vars) and a WORD_LIST * for the
+         remaining (rest_of_args). Fixes performance issue with function calls
+         and large numbers of positional parameters raised by
+         Bize Ma <binaryzebra@gmail.com>
+       - {save,restore,free,free_saved}_dollar_vars: new functions to manage
+         dollar_vars and dollar_arg_stack members. Need to keep these in sync
+         with whatever remember_args does
+       - push_dollar_vars: use save_dollar_vars, which just copies pointers,
+         and directly assign rest_of_args, without copying the words, to the
+         dollar_arg_stack entry. Have to clear dollar_vars and rest_of_args
+         with the assumption that callers will call remember_args(args, 1)
+         immediately following
+       - pop_dollar_vars: free current positional parameters and restore old
+         ones from pointers saved in dollar_arg_stack, making sure to
+         invalidate any cached value for "$@"
+       - dispose_saved_dollar_vars: free saved pointers from current index
+         into dollar_arg_stack
+
+doc/{bash.1,bashref.texi}
+       - POSIXLY_CORRECT: make sure to note that bash makes sure this variable
+         is set when posix mode is enabled
+
+                                  8/17
+                                  ----
+{jobs,nojobs}.c
+       - set_jobs_list_frozen: set jobs_list_frozen to a particular value.
+         Intended to save and restore the value around code sections instead
+         of unconditionally unfreezing it.
+
+jobs.h
+       - set_jobs_list_frozen: extern declaration
+
+execute_cmd.c
+       - execute_pipeline: if lastpipe is enabled, save and restore the
+         value of jobs_list_frozen using freeze_jobs_list/set_jobs_list_frozen
+         to avoid problems with race conditions and nested pipelines
+         causing jobs to be removed from the jobs table. Fixes savannah issue
+         https://savannah.gnu.org/support/index.php?109541 reported by
+         Björn Kautler <vampire0>
index 6aec7404a5f7a8cf0707b7a189d1844194378a96..2b267561b6a098574b0bc81726c6ce32840f22ca 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -1376,6 +1376,8 @@ tests/varenv11.sub        f
 tests/varenv12.sub     f
 tests/varenv13.sub     f
 tests/varenv14.sub     f
+tests/varenv15.sub     f
+tests/varenv15.in      f
 tests/version          f
 tests/version.mini     f
 tests/vredir.tests     f
index 6ea6f40f9fa7927b1e77a96d21338b924ab3b520..6ed03e10b295d6773d779a7059b91e136057c8ea 100644 (file)
@@ -1307,7 +1307,7 @@ AC_CACHE_VAL(bash_cv_must_reinstall_sighandlers,
 
 typedef RETSIGTYPE sigfunc();
 
-int nsigint;
+volatile int nsigint;
 
 #ifdef HAVE_POSIX_SIGNALS
 sigfunc *
index 10b2b06a302fcf21fcc471f581c7e5c2f941c757..e3700dd3ec8092976e6ecd9231c405ec628a464b 100644 (file)
@@ -199,6 +199,8 @@ bind_array_var_internal (entry, ind, key, value, flags)
   FREE (newval);
 
   VUNSETATTR (entry, att_invisible);   /* no longer invisible */
+
+  /* check mark_modified_variables if we ever want to export array vars */
   return (entry);
 }
 
index 682cafecebb730a697042548e7285a509e2153cf..82e5ec36501ebcfa7b4e4b8f08eee24a3351fa1d 100755 (executable)
--- a/configure
+++ b/configure
@@ -15257,7 +15257,7 @@ else
 
 typedef RETSIGTYPE sigfunc();
 
-int nsigint;
+volatile int nsigint;
 
 #ifdef HAVE_POSIX_SIGNALS
 sigfunc *
index 9d1e5af272c17af827105077106b3c884ca0fca2..9561ed87a855fea6ca3e7e78ec547ae193e5a172 100644 (file)
@@ -2414,6 +2414,8 @@ running, \fBbash\fP enables \fIposix mode\fP, as if the command
 .if t \f(CWset -o posix\fP
 .if n \fIset -o posix\fP
 had been executed.
+When the shell enters \fIposix mode\fP, it sets this variable if it was
+not already set.
 .TP
 .B PROMPT_COMMAND
 If set, the value is executed as a command prior to issuing each primary
index ba9e2b5157bfa6656d10cdc5c90e2e640f912244..cb67c8a255b0d7d1aafba6f9d3409da079c13e50 100644 (file)
@@ -6189,7 +6189,9 @@ as if the command
 @code{set -o posix}
 @end example
 @noindent
-had been executed.  
+had been executed.
+When the shell enters @sc{posix} mode, it sets this variable if it was
+not already set.
 
 @item PPID
 The process @sc{id} of the shell's parent process.  This variable
@@ -7528,6 +7530,9 @@ startup files.
 The following list is what's changed when `@sc{posix} mode' is in effect:
 
 @enumerate
+@item
+Bash ensures that the @env{POSIXLY_CORRECT} variable is set.
+
 @item
 When a command in the hash table no longer exists, Bash will re-search
 @env{$PATH} to find the new location.  This is also available with
index 58d32c038bc57f1f9d6b8511d648aec91d20f8bd..68b9300631660cb5dfa71116c524c2666d77947a 100644 (file)
@@ -2448,7 +2448,7 @@ execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close)
      struct fd_bitmap *fds_to_close;
 {
   int prev, fildes[2], new_bitmap_size, dummyfd, ignore_return, exec_result;
-  int lstdin, lastpipe_flag, lastpipe_jid;
+  int lstdin, lastpipe_flag, lastpipe_jid, old_frozen;
   COMMAND *cmd;
   struct fd_bitmap *fd_bitmap;
   pid_t lastpid;
@@ -2563,7 +2563,7 @@ execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close)
          prev = NO_PIPE;
          add_unwind_protect (restore_stdin, lstdin);
          lastpipe_flag = 1;
-         freeze_jobs_list ();
+         old_frozen = freeze_jobs_list ();
          lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL);    /* XXX */
          add_unwind_protect (lastpipe_cleanup, lastpipe_jid);
        }
@@ -2611,9 +2611,9 @@ execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close)
       else if (pipefail_opt)
        exec_result = exec_result | lstdin;     /* XXX */
       /* otherwise we use exec_result */
-        
 #endif
-      unfreeze_jobs_list ();
+
+      set_jobs_list_frozen (old_frozen);
     }
 
   discard_unwind_frame ("lastpipe-exec");
diff --git a/jobs.c b/jobs.c
index dc322b1b3eeb64711213da4eb91dac2c37a69bd4..f517a248c18689cb22f8fa47982a1d002dc67f24 100644 (file)
--- a/jobs.c
+++ b/jobs.c
@@ -4771,6 +4771,13 @@ unfreeze_jobs_list ()
   jobs_list_frozen = 0;
 }
 
+void
+set_jobs_list_frozen (s)
+     int s;
+{
+  jobs_list_frozen = s;
+}
+
 /* Allow or disallow job control to take place.  Returns the old value
    of job_control. */
 int
diff --git a/jobs.h b/jobs.h
index 4eca6260942159d9a6577610d2b463256078ac29..6ebaf4de2a3b337d34548579fc55c3185d20c075 100644 (file)
--- a/jobs.h
+++ b/jobs.h
@@ -259,7 +259,8 @@ extern int give_terminal_to __P((pid_t, int));
 extern void run_sigchld_trap __P((int));
 
 extern int freeze_jobs_list __P((void));
-extern void unfreeze_jobs_list __P((void));
+extern void unfreeeze_jobs_list __P((void));
+extern void set_jobs_list_frozen __P((int));
 extern int set_job_control __P((int));
 extern void without_job_control __P((void));
 extern void end_job_control __P((void));
index 87ca2173c946e65065bebac5e805f886283afacb..6e5892ee701f41ed92a445b63bb389781e56824e 100644 (file)
@@ -142,9 +142,11 @@ extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int));
    302 / 1000 is log10 (2) rounded up;
    add one for integer division truncation;
    add one more for a minus sign if t is signed.  */
+#ifndef INT_STRLEN_BOUND
 #define INT_STRLEN_BOUND(t) \
   ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
      + 1 + TYPE_SIGNED (t))
+#endif
 
 /* conversion flags */
 #define PF_ALTFORM     0x00001         /* # */
index 472624b92168f93af3e19753f498156e6d49362c..2201a29ac9f927d2b4535d0508fb54d75acf09a6 100644 (file)
--- a/nojobs.c
+++ b/nojobs.c
@@ -1037,6 +1037,12 @@ unfreeze_jobs_list ()
 {
 }
 
+void
+set_jobs_list_frozen (s)
+     int s;
+{
+}
+
 int
 count_all_jobs ()
 {
index c2f00848c1da5d039dd3e28ec22eb3f750da5a23..4e8c0d167ac862d24898f4c3407209830ccfe729 100644 (file)
@@ -177,6 +177,36 @@ declare -a a=([0]="X" [1]="Y")
 declare -a s=([0]="X" [1]="Y")
 declare -a a=([0]="XY")
 declare -a s=([0]="XY")
+f: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
+f1: after: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+done: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
+f3:1
+f3:2
+f3:3
+f3:4
+f3:5
+f3:6
+f3:7
+f3:8
+f3:9
+f3:10
+f3:11
+f3:12
+f3:13
+f3:14
+f3:15
+f3:16
+f3:17
+f3:18
+f3:19
+f3:20
+before source: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+varenv15.in: before set: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+varenv15.in: after set: a b c d e f g h i j k l m n o p q r s t u v w x y z
+after source 1: a b c d e f g h i j k l m n o p q r s t u v w x y z
+varenv15.in: before set: one two three four five six seven eight nine ten
+varenv15.in: after set: a b c d e f g h i j k l m n o p q r s t u v w x y z
+after source 2: a b c d e f g h i j k l m n o p q r s t u v w x y z
 a=z
 a=b
 a=z
index 52d23fddc638a1f0d1f184f5a59495811e3268e1..34b8559633116b123a8eda2d994b28cf58c021bf 100644 (file)
@@ -240,5 +240,7 @@ ${THIS_SH} ./varenv13.sub
 # localvar_inherit
 ${THIS_SH} ./varenv14.sub
 
+${THIS_SH} ./varenv15.sub
+
 # make sure variable scoping is done right
 tt() { typeset a=b;echo a=$a; };a=z;echo a=$a;tt;echo a=$a
diff --git a/tests/varenv15.in b/tests/varenv15.in
new file mode 100644 (file)
index 0000000..e635b12
--- /dev/null
@@ -0,0 +1,3 @@
+echo varenv15.in: before set: "$@"
+set -- a b c d e f g h i j k l m n o p q r s t u v w x y z
+echo varenv15.in: after set: "$@"
diff --git a/tests/varenv15.sub b/tests/varenv15.sub
new file mode 100644 (file)
index 0000000..52c8a94
--- /dev/null
@@ -0,0 +1,38 @@
+# check saving and restoring positional parameters around function calls
+
+f()
+{
+       echo $FUNCNAME: "$@"
+}
+
+f1()
+{
+       f {1..50}
+       echo $FUNCNAME: after: $@
+}
+
+set -- {1..100}
+
+f1 {1..20}
+echo done: $@
+
+f3()
+{
+       echo $FUNCNAME:$1
+       shift
+       if [ $# -le 0 ]; then
+               return
+       fi
+       f3 "$@"
+}
+
+f3 {1..20}
+
+# now let's try source with and without positional parameters
+
+set -- {1..20}
+echo before source: "$@"
+. ./varenv15.in
+echo after source 1: "$@"
+. ./varenv15.in one two three four five six seven eight nine ten
+echo after source 2: "$@"
index 8336d073f501db9d04fd6d596980c536dd7aecf5..00872d6479db43e291e2a657dd418d090c7afc62 100644 (file)
@@ -5290,10 +5290,64 @@ pop_scope (is_special)
 /*                                                                 */
 /* **************************************************************** */
 
-static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
+struct saved_dollar_vars {
+  char **first_ten;
+  WORD_LIST *rest;
+};
+
+static struct saved_dollar_vars *dollar_arg_stack = (struct saved_dollar_vars *)NULL;
 static int dollar_arg_stack_slots;
 static int dollar_arg_stack_index;
 
+/* Functions to manipulate dollar_vars array. Need to keep these in sync with
+   whatever remember_args() does. */
+static char **
+save_dollar_vars ()
+{
+  char **ret;
+  int i;
+
+  ret = strvec_create (10);
+  for (i = 1; i < 10; i++)
+    {
+      ret[i] = dollar_vars[i];
+      dollar_vars[i] = (char *)NULL;
+    }
+  return ret;
+}
+
+static void
+restore_dollar_vars (args)
+     char **args;
+{
+  int i;
+
+  for (i = 1; i < 10; i++)
+    dollar_vars[i] = args[i];
+}
+
+static void
+free_dollar_vars ()
+{
+  int i;
+
+  for (i = 1; i < 10; i++)
+    {
+      FREE (dollar_vars[i]);
+      dollar_vars[i] = (char *)NULL;
+    }
+}
+
+static void
+free_saved_dollar_vars (args)
+     char **args;
+{
+  int i;
+
+  for (i = 1; i < 10; i++)
+    FREE (args[i]);
+}
+
 /* XXX - should always be followed by remember_args () */
 void
 push_context (name, is_subshell, tempvars)
@@ -5325,35 +5379,53 @@ push_dollar_vars ()
 {
   if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
     {
-      dollar_arg_stack = (WORD_LIST **)
+      dollar_arg_stack = (struct saved_dollar_vars *)
        xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
-                 * sizeof (WORD_LIST *));
+                 * sizeof (struct saved_dollar_vars));
     }
-  dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
-  dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
+  
+  dollar_arg_stack[dollar_arg_stack_index].first_ten = save_dollar_vars ();
+  dollar_arg_stack[dollar_arg_stack_index++].rest = rest_of_args;
+  rest_of_args = (WORD_LIST *)NULL;
+  
+  dollar_arg_stack[dollar_arg_stack_index].first_ten = (char **)NULL;
+  dollar_arg_stack[dollar_arg_stack_index].rest = (WORD_LIST *)NULL;  
 }
 
 /* Restore the positional parameters from our stack. */
 void
 pop_dollar_vars ()
 {
-  if (!dollar_arg_stack || dollar_arg_stack_index == 0)
+  if (dollar_arg_stack == 0 || dollar_arg_stack_index == 0)
     return;
 
-  remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
-  dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
-  dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
+  /* Do what remember_args (xxx, 1) would have done. */
+  free_dollar_vars ();
+  dispose_words (rest_of_args);
+  
+  rest_of_args = dollar_arg_stack[--dollar_arg_stack_index].rest;
+  restore_dollar_vars (dollar_arg_stack[dollar_arg_stack_index].first_ten);
+  free (dollar_arg_stack[dollar_arg_stack_index].first_ten);
+
+  dollar_arg_stack[dollar_arg_stack_index].first_ten = (char **)NULL;
+  dollar_arg_stack[dollar_arg_stack_index].rest = (WORD_LIST *)NULL;
+  
   set_dollar_vars_unchanged ();
+  invalidate_cached_quoted_dollar_at ();
 }
 
 void
 dispose_saved_dollar_vars ()
 {
-  if (!dollar_arg_stack || dollar_arg_stack_index == 0)
+  if (dollar_arg_stack == 0 || dollar_arg_stack_index == 0)
     return;
 
-  dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
-  dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
+  dispose_words (dollar_arg_stack[--dollar_arg_stack_index].rest);    
+  free_saved_dollar_vars (dollar_arg_stack[dollar_arg_stack_index].first_ten); 
+  free (dollar_arg_stack[dollar_arg_stack_index].first_ten);
+
+  dollar_arg_stack[dollar_arg_stack_index].first_ten = (char **)NULL;  
+  dollar_arg_stack[dollar_arg_stack_index].rest = (WORD_LIST *)NULL;
 }
 
 /* Initialize BASH_ARGV and BASH_ARGC after turning on extdebug after the