From: Chet Ramey Date: Wed, 21 Feb 2024 14:42:10 +0000 (-0500) Subject: fix quoting for positional parameters if not word splitting; retry open for startup... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=43ecbeb31e5bbbc1a7557243af82b9f3e6390ced;p=thirdparty%2Fbash.git fix quoting for positional parameters if not word splitting; retry open for startup files on EINTR; update HISTIGNORE description --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index e237bcda..9b6b711f 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -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 diff --git a/bashhist.c b/bashhist.c index 9e762057..98e5cabc 100644 --- a/bashhist.c +++ b/bashhist.c @@ -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 diff --git a/builtins/evalfile.c b/builtins/evalfile.c index 6a242bda..17a568a0 100644 --- a/builtins/evalfile.c +++ b/builtins/evalfile.c @@ -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); diff --git a/doc/bash.1 b/doc/bash.1 index 66854edc..65bd81ce 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -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 ). diff --git a/doc/bashref.texi b/doc/bashref.texi index 344fd94a..dedfce9e 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -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{*}). diff --git a/doc/version.texi b/doc/version.texi index 4e6a512e..a0bd72ca 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -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 diff --git a/lib/readline/bind.c b/lib/readline/bind.c index 9744ae2f..af3d70ec 100644 --- a/lib/readline/bind.c +++ b/lib/readline/bind.c @@ -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); } diff --git a/lib/readline/histfile.c b/lib/readline/histfile.c index 2af71d35..e4d0b37a 100644 --- a/lib/readline/histfile.c +++ b/lib/readline/histfile.c @@ -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 1bf2ea29..7a04d71e 100644 --- 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); diff --git a/tests/dollar-star11.sub b/tests/dollar-star11.sub index 25d30be0..551c3076 100644 --- a/tests/dollar-star11.sub +++ b/tests/dollar-star11.sub @@ -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 . +# + 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 diff --git a/tests/dollar.right b/tests/dollar.right index 7041fd37..afb74484 100644 --- a/tests/dollar.right +++ b/tests/dollar.right @@ -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