mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-27 15:43:18 +02:00
fix quoting for positional parameters if not word splitting; retry open for startup files on EINTR; update HISTIGNORE description
This commit is contained in:
@@ -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>
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
+21
-13
@@ -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);
|
||||
|
||||
+8
-3
@@ -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 ).
|
||||
|
||||
@@ -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{*}).
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+14
-2
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user