From: Chet Ramey Date: Mon, 17 Nov 2025 19:50:43 +0000 (-0500) Subject: fix for a trap on SIGINT restoring the default disposition in an asynchronous subshel... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2fd02c838775741b6693e8f9819a8c167f839b55;p=thirdparty%2Fbash.git 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 --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index e9aa8b9e..fab80135 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -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 diff --git a/arrayfunc.c b/arrayfunc.c index fd3ebb1a..3f34370e 100644 --- a/arrayfunc.c +++ b/arrayfunc.c @@ -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 diff --git a/builtins/cd.def b/builtins/cd.def index 108862b8..b9ad86c6 100644 --- a/builtins/cd.def +++ b/builtins/cd.def @@ -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 diff --git a/doc/bash.1 b/doc/bash.1 index b0fa1ef0..42c89441 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -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. diff --git a/doc/bashref.texi b/doc/bashref.texi index 7410d2fa..f78bd7e5 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -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 diff --git a/execute_cmd.c b/execute_cmd.c index e2e0b4f0..a0b66015 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -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 diff --git a/externs.h b/externs.h index d73b5a1a..ca0c6c39 100644 --- a/externs.h +++ b/externs.h @@ -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); diff --git a/lib/termcap/termcap.c b/lib/termcap/termcap.c index 2b47062e..a18af160 100644 --- a/lib/termcap/termcap.c +++ b/lib/termcap/termcap.c @@ -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) { diff --git a/shell.c b/shell.c index 8e595d33..6ea54fde 100644 --- a/shell.c +++ b/shell.c @@ -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 diff --git a/tests/comsub2.right b/tests/comsub2.right index 6e21c5ca..2ec85261 100644 --- a/tests/comsub2.right +++ b/tests/comsub2.right @@ -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" ) diff --git a/tests/errors.right b/tests/errors.right index e7fd363c..429f2d49 100644 --- a/tests/errors.right +++ b/tests/errors.right @@ -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 +./errors.tests: line 237: cd: /notthere: No such file or directory +2 +./errors.tests: line 240: .: filename argument required .: usage: . [-p path] filename [arguments] -./errors.tests: line 239: source: filename argument required +./errors.tests: line 241: source: filename argument required source: usage: source [-p path] filename [arguments] -./errors.tests: line 242: .: -i: invalid option +./errors.tests: line 244: .: -i: invalid option .: usage: . [-p path] filename [arguments] -./errors.tests: line 245: set: -q: invalid option +./errors.tests: line 247: 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 +./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 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 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 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 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 diff --git a/tests/errors.tests b/tests/errors.tests index 822feb0d..85d5dae1 100644 --- a/tests/errors.tests +++ b/tests/errors.tests @@ -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 . diff --git a/trap.c b/trap.c index aba08fea..ea103f58 100644 --- a/trap.c +++ b/trap.c @@ -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; }