fix for a trap on SIGINT restoring the default disposition in an asynchronous subshell; change cd exit status if -Pe supplied and the directory can't be changed; fix for compound associative array assignment if one of the expanded words unsets the array during word expansion; fixes for rare systems that don't have various defines and system calls

This commit is contained in:
Chet Ramey
2025-11-17 14:50:43 -05:00
parent 81d8584268
commit 2fd02c8387
13 changed files with 113 additions and 62 deletions
+37
View File
@@ -12191,3 +12191,40 @@ jobs.c
builtins/read.def
- read_builtin: POSIX says read must return >1 on a read error, 1
is reserved for EOF
11/7
----
trap.c
- restore_default_signal: if we're restoring the default signal
disposition for a signal that was ignored due to SIG_ASYNCSIG,
make sure to mark the signal as not trapped after calling
change_signal (..., DEFAULT_SIG)
builtins/cd.def
- cd_builtin: POSIX says to return >1 if -P and -e are supplied and
the directory can't be changed
11/11
-----
arrayfunc.c
- assign_compound_array_list: paranoia: make sure to set att_assoc
after assigning a kvpair-style list; the array could have been
unset by some perverse script. This makes kvpair assignment, assoc
subscripted compound assignment, and indexed array subscripted
compound assignment behave consistently
11/12
-----
externs.h
- gethostname, killpg: fixed prototypes for functions defined in
lib/sh/oslib.c
From andrew@andrewoates.com
lib/termcap/termcap.c,shell.c
- lseek: use symbolic constants instead of 0 and 1
From andrew@andrewoates.com
execute_cmd.c
- time_command: make usage of the various preprocessor defines that
determine how we measure the command's duration consistent
From andrew@andrewoates.com
+1
View File
@@ -756,6 +756,7 @@ assign_compound_array_list (SHELL_VAR *var, WORD_LIST *nlist, int flags)
var_setassoc (var, nhash);
assoc_dispose (h);
}
VSETATTR(var, att_assoc); /* paranoia; could have been unset */
return 1; /* XXX - check return value */
}
#endif
+1 -1
View File
@@ -429,7 +429,7 @@ cd_builtin (WORD_LIST *list)
if (temp != dirname)
free (temp);
/* posix says to return >1 if eflag && no_symlinks?? */
return (EXECUTION_FAILURE);
return ((eflag && no_symlinks) ? EX_MISCERROR : EXECUTION_FAILURE);
}
$BUILTIN pwd
+3
View File
@@ -3309,6 +3309,9 @@ using the compound assignment syntax; see
.B PARAMETERS
above.
.PP
If one of the word expansions in a compound array assignment unsets the
variable, the results are unspecified.
.PP
An array element is referenced using
${\fIname\fP[\fIsubscript\fP]}.
The braces are required to avoid conflicts with pathname expansion.
+3
View File
@@ -8761,6 +8761,9 @@ operator appends to an array variable when assigning
using the compound assignment syntax; see
@ref{Shell Parameters} above.
If one of the word expansions in a compound array assignment unsets the
variable, the results are unspecified.
An array element is referenced using
@code{$@{@var{name}[@var{subscript}]@}}.
The braces are required to avoid
+3 -5
View File
@@ -1497,21 +1497,19 @@ time_command (COMMAND *command, int asynchronous, int pipe_in, int pipe_out, str
getrusage (RUSAGE_SELF, &selfb);
getrusage (RUSAGE_CHILDREN, &kidsb);
gettimeofday (&before, NULL);
#else
# if defined (HAVE_TIMES)
#elif defined (HAVE_TIMES)
tbefore = times (&before);
# endif
#endif
/* In posix mode, `time' without argument is equivalent to `times', but
obeys TIMEFORMAT. This is from POSIX interp 267 */
if (posixly_correct && nullcmd)
{
#if defined (HAVE_GETRUSAGE)
#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
selfb.ru_utime.tv_sec = kidsb.ru_utime.tv_sec = selfb.ru_stime.tv_sec = kidsb.ru_stime.tv_sec = 0;
selfb.ru_utime.tv_usec = kidsb.ru_utime.tv_usec = selfb.ru_stime.tv_usec = kidsb.ru_stime.tv_usec = 0;
before = shellstart;
#else
#elif defined (HAVE_TIMES)
before.tms_utime = before.tms_stime = before.tms_cutime = before.tms_cstime = 0;
tbefore = shell_start_time * get_clk_tck ();
#endif
+5 -1
View File
@@ -309,9 +309,13 @@ extern int getdtablesize (void);
#endif /* !HAVE_GETDTABLESIZE */
#if !defined (HAVE_GETHOSTNAME)
extern int gethostname (char *, int);
extern int gethostname (char *, size_t);
#endif /* !HAVE_GETHOSTNAME */
#if !defined (HAVE_KILLPG)
extern int killpg (pid_t, int);
#endif /* !HAVE_KILLPG */
extern int getmaxgroups (void);
extern long getmaxchild (void);
+1 -1
View File
@@ -611,7 +611,7 @@ scan_file (char *str, int fd, struct buffer *bufp)
bufp->ateof = 0;
*bufp->ptr = '\0';
lseek (fd, 0L, 0);
lseek (fd, 0L, SEEK_SET);
while (!bufp->ateof)
{
+2 -2
View File
@@ -1654,7 +1654,7 @@ open_shell_script (char *script_name)
#endif
/* Only do this with non-tty file descriptors we can seek on. */
if (fd_is_tty == 0 && (lseek (fd, 0L, 1) != -1))
if (fd_is_tty == 0 && (lseek (fd, 0L, SEEK_CUR) != -1))
{
/* Check to see if the `file' in `bash file' is a binary file
according to the same tests done by execute_simple_command (),
@@ -1691,7 +1691,7 @@ open_shell_script (char *script_name)
exit (EX_BINARY_FILE);
}
/* Now rewind the file back to the beginning. */
lseek (fd, 0L, 0);
lseek (fd, 0L, SEEK_SET);
}
/* Open the script. But try to move the file descriptor to a randomly
+1 -1
View File
@@ -220,7 +220,7 @@ declare -ai a=()
./comsub27.sub: line 61: b[]: bad array subscript
./comsub27.sub: line 61: b[]: bad array subscript
declare -ai a=([0]="1" [1]="0" [2]="3")
declare -Ai a=([0]="" )
declare -Ai a=()
./comsub27.sub: line 71: b[]: bad array subscript
./comsub27.sub: line 71: b[]: bad array subscript
declare -Ai a=([3]="0" [1]="0" )
+53 -51
View File
@@ -80,67 +80,69 @@ bash: line 1: PWD: readonly variable
1
bash: line 1: OLDPWD: readonly variable
1
./errors.tests: line 238: .: filename argument required
.: usage: . [-p path] filename [arguments]
./errors.tests: line 239: source: filename argument required
source: usage: source [-p path] filename [arguments]
./errors.tests: line 242: .: -i: invalid option
.: usage: . [-p path] filename [arguments]
./errors.tests: line 245: set: -q: invalid option
set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]
./errors.tests: line 248: enable: sh: not a shell builtin
./errors.tests: line 248: enable: bash: not a shell builtin
./errors.tests: line 251: shopt: cannot set and unset shell options simultaneously
./errors.tests: line 254: read: -x: invalid option
read: usage: read [-Eers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
./errors.tests: line 257: read: var: invalid timeout specification
./errors.tests: line 260: read: `/bin/sh': not a valid identifier
./errors.tests: line 261: read: `/bin/sh': not a valid identifier
./errors.tests: line 262: read: `invalid-name': not a valid identifier
./errors.tests: line 265: VAR: readonly variable
./errors.tests: line 268: read: XX: invalid file descriptor specification
./errors.tests: line 269: read: 42: invalid file descriptor: Bad file descriptor
./errors.tests: line 270: read: 0: read error: Bad file descriptor
./errors.tests: line 237: cd: /notthere: No such file or directory
2
./errors.tests: line 273: mapfile: XX: invalid file descriptor specification
./errors.tests: line 274: mapfile: 42: invalid file descriptor: Bad file descriptor
./errors.tests: line 278: mapfile: empty array variable name
./errors.tests: line 279: mapfile: `invalid-var': not a valid identifier
./errors.tests: line 282: readonly: -x: invalid option
./errors.tests: line 240: .: filename argument required
.: usage: . [-p path] filename [arguments]
./errors.tests: line 241: source: filename argument required
source: usage: source [-p path] filename [arguments]
./errors.tests: line 244: .: -i: invalid option
.: usage: . [-p path] filename [arguments]
./errors.tests: line 247: set: -q: invalid option
set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]
./errors.tests: line 250: enable: sh: not a shell builtin
./errors.tests: line 250: enable: bash: not a shell builtin
./errors.tests: line 253: shopt: cannot set and unset shell options simultaneously
./errors.tests: line 256: read: -x: invalid option
read: usage: read [-Eers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
./errors.tests: line 259: read: var: invalid timeout specification
./errors.tests: line 262: read: `/bin/sh': not a valid identifier
./errors.tests: line 263: read: `/bin/sh': not a valid identifier
./errors.tests: line 264: read: `invalid-name': not a valid identifier
./errors.tests: line 267: VAR: readonly variable
./errors.tests: line 270: read: XX: invalid file descriptor specification
./errors.tests: line 271: read: 42: invalid file descriptor: Bad file descriptor
./errors.tests: line 272: read: 0: read error: Bad file descriptor
2
./errors.tests: line 275: mapfile: XX: invalid file descriptor specification
./errors.tests: line 276: mapfile: 42: invalid file descriptor: Bad file descriptor
./errors.tests: line 280: mapfile: empty array variable name
./errors.tests: line 281: mapfile: `invalid-var': not a valid identifier
./errors.tests: line 284: readonly: -x: invalid option
readonly: usage: readonly [-aAf] [name[=value] ...] or readonly -p
./errors.tests: line 285: eval: -i: invalid option
./errors.tests: line 287: eval: -i: invalid option
eval: usage: eval [arg ...]
./errors.tests: line 286: command: -i: invalid option
./errors.tests: line 288: command: -i: invalid option
command: usage: command [-pVv] command [arg ...]
./errors.tests: line 289: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 290: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 293: trap: NOSIG: invalid signal specification
./errors.tests: line 296: trap: -s: invalid option
./errors.tests: line 291: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 292: /bin/sh + 0: arithmetic syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 295: trap: NOSIG: invalid signal specification
./errors.tests: line 298: trap: -s: invalid option
trap: usage: trap [-Plp] [[action] signal_spec ...]
./errors.tests: line 302: return: can only `return' from a function or sourced script
./errors.tests: line 306: break: 0: loop count out of range
./errors.tests: line 310: continue: 0: loop count out of range
./errors.tests: line 315: builtin: -x: invalid option
./errors.tests: line 304: return: can only `return' from a function or sourced script
./errors.tests: line 308: break: 0: loop count out of range
./errors.tests: line 312: continue: 0: loop count out of range
./errors.tests: line 317: builtin: -x: invalid option
builtin: usage: builtin [shell-builtin [arg ...]]
./errors.tests: line 318: builtin: bash: not a shell builtin
./errors.tests: line 322: bg: no job control
./errors.tests: line 323: fg: no job control
./errors.tests: line 320: builtin: bash: not a shell builtin
./errors.tests: line 324: bg: no job control
./errors.tests: line 325: fg: no job control
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
./errors.tests: line 327: kill: -s: option requires an argument
./errors.tests: line 329: kill: S: invalid signal specification
./errors.tests: line 331: kill: `': not a pid or valid job spec
./errors.tests: line 329: kill: -s: option requires an argument
./errors.tests: line 331: kill: S: invalid signal specification
./errors.tests: line 333: kill: `': not a pid or valid job spec
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
./errors.tests: line 335: kill: SIGBAD: invalid signal specification
./errors.tests: line 337: kill: BAD: invalid signal specification
./errors.tests: line 339: kill: `@12': not a pid or valid job spec
./errors.tests: line 342: unset: BASH_LINENO: cannot unset
./errors.tests: line 342: unset: BASH_SOURCE: cannot unset
./errors.tests: line 345: set: trackall: invalid option name
./errors.tests: line 346: set: -q: invalid option
./errors.tests: line 337: kill: SIGBAD: invalid signal specification
./errors.tests: line 339: kill: BAD: invalid signal specification
./errors.tests: line 341: kill: `@12': not a pid or valid job spec
./errors.tests: line 344: unset: BASH_LINENO: cannot unset
./errors.tests: line 344: unset: BASH_SOURCE: cannot unset
./errors.tests: line 347: set: trackall: invalid option name
./errors.tests: line 348: set: -q: invalid option
set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]
./errors.tests: line 347: set: -i: invalid option
./errors.tests: line 349: set: -i: invalid option
set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]
./errors.tests: line 351: xx: readonly variable
./errors.tests: line 353: xx: readonly variable
1
errors1.sub
./errors1.sub: line 14: .: -i: invalid option
+2
View File
@@ -233,6 +233,8 @@ cd one two three
${THIS_SH} -c 'readonly PWD ; cd / ; echo $?' bash
# or if OLDPWD is readonly
${THIS_SH} -c 'readonly OLDPWD ; cd / ; echo $?' bash
# POSIX says to return >1 if -P and -e are supplied and an error occurs
cd -Pe /notthere ; echo $?
# various `source/.' errors
.
+1
View File
@@ -965,6 +965,7 @@ restore_default_signal (int sig)
original_signals[sig] = SIG_DFL; /* XXX */
set_signal_handler (sig, SIG_DFL);
change_signal (sig, (char *)DEFAULT_SIG);
sigmodes[sig] &= ~SIG_TRAPPED; /* no longer trapped */
return;
}