]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
fix quoting for positional parameters if not word splitting; retry open for startup...
authorChet Ramey <chet.ramey@case.edu>
Wed, 21 Feb 2024 14:42:10 +0000 (09:42 -0500)
committerChet Ramey <chet.ramey@case.edu>
Wed, 21 Feb 2024 14:42:10 +0000 (09:42 -0500)
CWRU/CWRU.chlog
bashhist.c
builtins/evalfile.c
doc/bash.1
doc/bashref.texi
doc/version.texi
lib/readline/bind.c
lib/readline/histfile.c
subst.c
tests/dollar-star11.sub
tests/dollar.right

index e237bcdab8cf04137c2ca960e29a9081f77d338d..9b6b711f4a6449d1e4482742682122fee4476774 100644 (file)
@@ -8678,6 +8678,9 @@ builtins/pushd.def,examples/loadables/necho.c
 subst.c,subst.h
        - rename quote_rhs -> quote_nosplit
 
+                                  2/19
+                                  ----
+
 subst.c
        - quote_var_value: break the code that quotes a variable value ($x,
          ${x}, ${x[n]}, etc.) into a separate inline function and call it
@@ -8701,3 +8704,30 @@ subst.c
          AV_ASSIGNRHS if we are expanding unquoted ${A[*]} in a place where
          word splitting does not occur with a non-null $IFS; array_value will
          quote appropriately here
+       - parameter_brace_expand_word,param_expand: use quote_var_value when
+         expanding $N and ${N}
+
+doc/bash.1,doc/bashref.texi
+       - HISTIGNORE: clarify the description a little to emphasize that lines
+         matching one of the patterns are not saved in the history list
+         From https://savannah.gnu.org/support/index.php?111020
+
+                                  2/20
+                                  ----
+builtins/evalfile.c
+       - FEVAL_RETRY: if set in FLAGS, _evalfile will retry an interrupted
+         open
+       - _evalfile: if open() returns -1, FEVAL_RETRY is set in FLAGS, and
+         errno == EINTR, retry the open after checking for interrupts or
+         terminating signals
+       - maybe_execute_file,force_execute_file: pass FEVAL_RETRY in flags
+
+bashhist.c
+       - load_history: retry read_history if it returns EINTR after checking
+         for interrupts or terminating signals 
+
+lib/readline/bind.c
+       - _rl_read_init_file: retry the open once if it's interrupted due to a
+         signal. If we are at a point where readline has installed its
+         signal handlers, check for signals readline handles
+         From a patch from Grisha Levit <grishalevit@gmail.com>
index 9e762057ea100f30e9df556c8fa629a69f5b796e..98e5cabcd07610fc46987e80aa9fc5a4f906efe5 100644 (file)
@@ -336,7 +336,8 @@ load_history (void)
 
   if (hf && *hf && file_exists (hf))
     {
-      read_history (hf);
+      while (read_history (hf) == EINTR)       /* 0 on success */
+       QUIT;
       /* We have read all of the lines from the history file, even if we
         read more lines than $HISTSIZE.  Remember the total number of lines
         we read so we don't count the last N lines as new over and over
index 6a242bda42ace8d2fb1e679eabb3bfd6de13ef4f..17a568a04c0d8fb2a1403e5b18decf0d3a24e811 100644 (file)
@@ -68,6 +68,7 @@ extern int errno;
 #define FEVAL_CHECKBINARY      0x040
 #define FEVAL_REGFILE          0x080
 #define FEVAL_NOPUSHARGS       0x100
+#define FEVAL_RETRY            0x200
 
 /* How many `levels' of sourced files we have. */
 int sourcelevel = 0;
@@ -96,17 +97,16 @@ _evalfile (const char *filename, int flags)
 
   USE_VAR(pflags);
 
-#if defined (ARRAY_VARS)
-  GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
-  GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
-  GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
-#  if defined (DEBUGGER)
-  GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
-  GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
-#  endif
-#endif
-
-  fd = open (filename, O_RDONLY);
+  errno = 0;
+  do
+    {
+      fd = open (filename, O_RDONLY);
+      i = errno;
+      if (fd < 0 && i == EINTR)
+        QUIT;
+      errno = i;
+    }
+  while (fd < 0 && errno == EINTR && (flags & FEVAL_RETRY));
 
   if (fd < 0 || (fstat (fd, &finfo) == -1))
     {
@@ -236,6 +236,14 @@ file_error_and_exit:
   retain_fifos++;                      /* XXX */
 
 #if defined (ARRAY_VARS)
+  GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
+  GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
+  GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
+#  if defined (DEBUGGER)
+  GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a);
+  GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
+#  endif
+
   array_push (bash_source_a, (char *)filename);
   t = itos (executing_line_number ());
   array_push (bash_lineno_a, t);
@@ -326,7 +334,7 @@ maybe_execute_file (const char *fname, int force_noninteractive)
   int result, flags;
 
   filename = bash_tilde_expand (fname, 0);
-  flags = FEVAL_ENOENTOK;
+  flags = FEVAL_ENOENTOK|FEVAL_RETRY;
   if (force_noninteractive)
     flags |= FEVAL_NONINT;
   result = _evalfile (filename, flags);
@@ -341,7 +349,7 @@ force_execute_file (const char *fname, int force_noninteractive)
   int result, flags;
 
   filename = bash_tilde_expand (fname, 0);
-  flags = 0;
+  flags = FEVAL_RETRY;
   if (force_noninteractive)
     flags |= FEVAL_NONINT;
   result = _evalfile (filename, flags);
index 66854edc111a42cb494231c71a46f07ea97283f9..65bd81cee47440693866910a0c9e9e9768211bb2 100644 (file)
@@ -5,14 +5,14 @@
 .\"    Case Western Reserve University
 .\"    chet.ramey@case.edu
 .\"
-.\"    Last Change: Mon Feb  5 10:51:21 EST 2024
+.\"    Last Change: Mon Feb 19 16:52:45 EST 2024
 .\"
 .\" bash_builtins, strip all but Built-Ins section
 .\" avoid a warning about an undefined register
 .\" .if !rzY .nr zY 0
 .if \n(zZ=1 .ig zZ
 .if \n(zY=1 .ig zY
-.TH BASH 1 "2024 February 5" "GNU Bash 5.3"
+.TH BASH 1 "2024 February 19" "GNU Bash 5.3"
 .\"
 .\" There's some problem with having a `@'
 .\" in a tagged paragraph with the BSD man macros.
@@ -2408,7 +2408,12 @@ after reading any startup files.
 .TP
 .B HISTIGNORE
 A colon-separated list of patterns used to decide which command lines
-should be saved on the history list.  Each pattern is anchored at the
+should be saved on the history list.
+If a command line matches one of the patterns in the value of
+.SM
+.BR HISTIGNORE ,
+it is not saved on the history list.
+Each pattern is anchored at the
 beginning of the line and must match the complete line
 (\fBbash\fP will not  implicitly append a
 .Q \fB*\fP ).
index 344fd94a866102b42b42b7989db65cb8e8808266..dedfce9e07c2bf7c6d05636d170c33ea1d260ebd 100644 (file)
@@ -6772,6 +6772,8 @@ after reading any startup files.
 @item HISTIGNORE
 A colon-separated list of patterns used to decide which command
 lines should be saved on the history list.
+If a command line matches one of the patterns in the value of
+@code{HISTIGNORE}, it is not saved on the history list.
 Each pattern is
 anchored at the beginning of the line and must match the complete
 line (Bash will not implicitly append a @samp{*}).
index 4e6a512ecf77464486c9b7cca9950a1f02db7b1f..a0bd72ca73e35de0a3215a50ab9254e068772f3f 100644 (file)
@@ -2,10 +2,10 @@
 Copyright (C) 1988-2024 Free Software Foundation, Inc.
 @end ignore
 
-@set LASTCHANGE Fri Feb  2 09:37:55 EST 2024
+@set LASTCHANGE Mon Feb 19 16:52:26 EST 2024
 
 @set EDITION 5.3
 @set VERSION 5.3
 
-@set UPDATED 2 February 2024
+@set UPDATED 19 February 2024
 @set UPDATED-MONTH February 2024
index 9744ae2f48d2d17506d0522aaaa1b3ef0c1bfb00..af3d70eca2f16144dd1b73172c3249a6a3185f52 100644 (file)
@@ -968,11 +968,20 @@ _rl_read_file (char *filename, size_t *sizep)
   char *buffer;
   int i, file;
 
-  file = -1;
-  if (((file = open (filename, O_RDONLY, 0666)) < 0) || (fstat (file, &finfo) < 0))
+  file = open (filename, O_RDONLY, 0666);
+  /* If the open is interrupted, retry once */
+  if (file < 0 && errno == EINTR)
     {
+      RL_CHECK_SIGNALS ();
+      file = open (filename, O_RDONLY, 0666);
+    }
+  
+  if ((file < 0) || (fstat (file, &finfo) < 0))
+    {
+      i = errno;
       if (file >= 0)
        close (file);
+      errno = i;
       return ((char *)NULL);
     }
 
@@ -981,10 +990,13 @@ _rl_read_file (char *filename, size_t *sizep)
   /* check for overflow on very large files */
   if (file_size != finfo.st_size || file_size + 1 < file_size)
     {
+      i = errno;
       if (file >= 0)
        close (file);
 #if defined (EFBIG)
       errno = EFBIG;
+#else
+      errno = i;
 #endif
       return ((char *)NULL);
     }
index 2af71d35255c644ade154c8fcaca1a30fff5dcc5..e4d0b37a785ea347f5a0b9492dd44c9a9e262602 100644 (file)
@@ -168,9 +168,8 @@ history_filename (const char *filename)
 
   if (home == 0)
     return (NULL);
-  else
-    home_len = strlen (home);
 
+  home_len = strlen (home);
   return_val = (char *)xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */
   strcpy (return_val, home);
   return_val[home_len] = '/';
@@ -282,7 +281,10 @@ read_history_range (const char *filename, int from, int to)
 
   buffer = last_ts = (char *)NULL;
   input = history_filename (filename);
-  file = input ? open (input, O_RDONLY|O_BINARY, 0666) : -1;
+  if (input == 0)
+    return 0;
+  errno = 0;
+  file = open (input, O_RDONLY|O_BINARY, 0666);
 
   if ((file < 0) || (fstat (file, &finfo) == -1))
     goto error_and_exit;
@@ -524,8 +526,10 @@ history_truncate_file (const char *fname, int lines)
 
   buffer = (char *)NULL;
   filename = history_filename (fname);
+  if (filename == 0)
+    return 0;
   tempname = 0;
-  file = filename ? open (filename, O_RDONLY|O_BINARY, 0666) : -1;
+  file = open (filename, O_RDONLY|O_BINARY, 0666);
   rv = exists = 0;
 
   orig_lines = lines;
diff --git a/subst.c b/subst.c
index 1bf2ea296efbb59484b97982f3fde3cb03a855f2..7a04d71e44c05fd50d95a716d80fd940432ca705 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -7632,12 +7632,7 @@ parameter_brace_expand_word (char *name, int var_is_special, int quoted, int pfl
   if (valid_number (name, &arg_index))
     {
       tt = get_dollar_var_value (arg_index);
-      if (tt)
-       temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
-                 ? quote_string (tt)
-                 : quote_escapes (tt);
-      else
-        temp = (char *)NULL;
+      temp = quote_var_value (tt, quoted, pflags);
       FREE (tt);
     }
   else if (var_is_special)      /* ${@} */
@@ -10443,13 +10438,7 @@ param_expand (char *string, size_t *sindex, int quoted,
          err_unboundvar (uerror);
          return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
        }
-      if (temp1)
-       temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
-                 ? quote_string (temp1)
-                 : quote_escapes (temp1);
-      else
-       temp = (char *)NULL;
-
+      temp = quote_var_value (temp1, quoted, pflags);
       break;
 
     /* $$ -- pid of the invoking shell. */
@@ -10907,7 +10896,7 @@ comsub:
 
          /* Quote the value appropriately */
          if (temp == 0 && unbound_vars_is_error)
-           goto unbound_variable;
+           goto unbound_variable;      /* can happen if array[0] is not set */
          else
            temp = quote_var_value (temp, quoted, pflags);
 
index 25d30be0270559c4461bcde5ddb65f9b1f3120e4..551c3076479130611e83ab34f0276231d3b1c742 100644 (file)
@@ -1,3 +1,17 @@
+#   This program is free software: you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
 set aa bb cc -- dd ; f=$'\1' IFS=$f
 
 recho "$f$*$f"
@@ -41,3 +55,44 @@ A=( aa bb cc -- dd ); f=$'\1' IFS=$f
 
 [[ ${f}${A[*]}${f} == $f${A[*]}$f ]] && echo ok 23
 [[ ${A[*]} == ${A[*]} ]] && echo ok 24
+
+# now test $N/${N}/${A[N]}
+set aa bb $'\1' cc -- dd ; f=$'\1' IFS=$f
+
+[[ $3$*$3 == $3$*$3 ]] && echo ok 25
+[[ $3$*$3 == ${3}${*}${3} ]] && echo ok 26
+[[ $3$*$3 == $3${*}${3} ]] && echo ok 27
+[[ $* == *$3* ]]&& echo ok 28
+[[ $* == *${3}* ]]&& echo ok 29
+
+# now use an array instead of $*
+A=( aa bb $'\1' cc -- dd )
+
+[[ ${A[2]}${A[*]}${A[2]} == ${A[2]}${A[*]}${A[2]} ]] && echo ok 30
+[[ ${A[2]}$*${A[2]} == ${A[2]}${*}${A[2]} ]] && echo ok 31
+[[ ${A[2]}$*${A[2]} == ${A[2]}${*}${A[2]} ]] && echo ok 32
+[[ $* == *${A[2]}* ]]&& echo ok 33
+[[ $* == *${A[2]}* ]]&& echo ok 34
+
+unset -v A
+
+set -- aa bb cc -- dd
+case $* in
+"$*")  echo ok 35;;
+*)     echo bad 35;;
+esac
+
+case $f in
+$f)    echo ok 36;;
+*)     echo bad 36;;
+esac
+
+case $f$*$f in
+$f"$*"$f)      echo ok 37;;
+*)     echo bad 37;;
+esac
+
+case $f$*$f in
+*$f--$f*)      echo ok 38;;
+*)     echo bad 38;;
+esac
index 7041fd37620eadcef514cc5fe9c7d30842392670..afb744840dce4ec72f1d9e14b795051cc884cc6a 100644 (file)
@@ -768,3 +768,17 @@ ok 21
 ok 22
 ok 23
 ok 24
+ok 25
+ok 26
+ok 27
+ok 28
+ok 29
+ok 30
+ok 31
+ok 32
+ok 33
+ok 34
+ok 35
+ok 36
+ok 37
+ok 38