mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-13 11:42:21 +00:00
POSIX: 'command': don't disable declaration proprts (re: b9d10c5a
)
Following the resolution of Austin Group bug 1393[*] that is set to be included in the next version of the POSIX standard, the 'command' prefix in POSIX mode (set -o posix) no longer disables the declaration properties of declaration built-ins. [*] https://austingroupbugs.net/view.php?id=1393 src/cmd/ksh93/sh/parse.c: lex(): - Skip the 'command' prefix even in POSIX mode so that any declaration commands prefixed by it are treated as such in xec.c (sh_exec()). src/cmd/ksh93/sh/xec.c: sh_exec(): - The foregoing change reintroduced a variant of BUG_CMDSPEXIT: the shell exits on something like 'command export readonlyvar=foo'. This now fixes that bug for both POSIX and non-POSIX mode. When calling nv_setlist() to process true shell assignments, and there is a 'command' prefix, push a shell context and use sigsetjmp to intercept any errors in assignments and stop the shell exiting. src/cmd/ksh93/tests/builtins.sh: - Borrow the BUG_CMDSPEXIT regression test from modernish and adapt it for ksh. (I'm the author so yes, I can do this.) Original: https://github.com/modernish/modernish/blob/ae8fe9c3/lib/modernish/tst/builtin.t#L80-L109
This commit is contained in:
parent
1a1e3709c2
commit
d309d604e7
5 changed files with 50 additions and 12 deletions
6
NEWS
6
NEWS
|
@ -17,6 +17,12 @@ Any uppercase BUG_* names are modernish shell bug IDs.
|
|||
- Completed the 2021-04-30 fix for ${var<OP>'{}'} where <OP> is '-', '+',
|
||||
':-' or ':+' by fixing a bug that caused an extra '}' to be output.
|
||||
|
||||
- Following the resolution of Austin Group bug 1393[*] that is set to be
|
||||
included in the next version of the POSIX standard, the 'command' prefix
|
||||
in POSIX mode (set -o posix) no longer disables the declaration properties
|
||||
of declaration built-ins. This reverts a change introduced on 2020-09-11.
|
||||
[*] https://austingroupbugs.net/view.php?id=1393
|
||||
|
||||
2021-04-30:
|
||||
|
||||
- The emacs 'ESC .' (M-.) and vi '_' commands now take shell quoting into
|
||||
|
|
|
@ -5913,13 +5913,6 @@ executing the command as a regular built-in.
|
|||
.I "option-name"
|
||||
prevents a script from terminating when an invalid
|
||||
option name is given.)
|
||||
If
|
||||
.I name\^
|
||||
refers to a declaration built-in,
|
||||
as marked with \fB\(dd\fR in this manual,
|
||||
and the \fBposix\fR shell option is on,
|
||||
then the declaration properties are removed so that arguments containing
|
||||
\fB=\fR are not treated specially.
|
||||
.IP
|
||||
The
|
||||
.B \-p
|
||||
|
@ -7246,9 +7239,6 @@ disables the \fB&>\fR redirection shorthand;
|
|||
.IP \[bu]
|
||||
makes the \fB<>\fR redirection operator default to redirecting standard input
|
||||
if no file descriptor number precedes it;
|
||||
.IP \[bu]
|
||||
causes the \fBcommand\fR utility to disable declaration command properties of
|
||||
any declaration commands it invokes;
|
||||
and
|
||||
.IP \[bu]
|
||||
disables a hack that makes \fBtest -t\fR (\fB[ -t ]\fR) equivalent to
|
||||
|
|
|
@ -1456,7 +1456,7 @@ static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io)
|
|||
lexp->intypeset = 1;
|
||||
key_on = 1;
|
||||
}
|
||||
else if(np==SYSCOMMAND && !sh_isoption(SH_POSIX))
|
||||
else if(np==SYSCOMMAND) /* treat 'command typeset', etc. as declaration command */
|
||||
cmdarg++;
|
||||
else if(np==SYSEXEC || np==SYSREDIR)
|
||||
lexp->inexec = 1;
|
||||
|
|
|
@ -1172,7 +1172,24 @@ int sh_exec(register const Shnode_t *t, int flags)
|
|||
flgs |= NV_IDENT;
|
||||
else
|
||||
flgs |= NV_VARNAME;
|
||||
nv_setlist(argp,flgs,tp);
|
||||
/* execute the list of assignments */
|
||||
if((!np || nv_isattr(np,BLT_SPC)) && !command)
|
||||
{
|
||||
/* bare assignment(s) or special builtin, and no 'command' prefix: exit on error */
|
||||
nv_setlist(argp,flgs,tp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* avoid exit on error from nv_setlist, e.g. read-only variable */
|
||||
struct checkpt *chkp = (struct checkpt*)stakalloc(sizeof(struct checkpt));
|
||||
sh_pushcontext(shp,chkp,SH_JMPCMD);
|
||||
jmpval = sigsetjmp(chkp->buff,1);
|
||||
if(!jmpval)
|
||||
nv_setlist(argp,flgs,tp);
|
||||
sh_popcontext(shp,chkp);
|
||||
if(jmpval) /* error occurred */
|
||||
goto setexit;
|
||||
}
|
||||
if(np==shp->typeinit)
|
||||
shp->typeinit = 0;
|
||||
shp->envlist = argp;
|
||||
|
|
|
@ -1241,5 +1241,30 @@ got=$("$SHELL" -c 'cd /; echo "$OLDPWD"' 2>&1)
|
|||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||
cd "$tmp"
|
||||
|
||||
# ======
|
||||
# BUG_CMDSPEXIT
|
||||
exp='ok1ok2ok3ok4ok5ok6ok7ok8ok9ok10ok11ok12end'
|
||||
got=$( readonly v=foo
|
||||
exec 2>/dev/null
|
||||
# All the "special builtins" below should fail, and not exit, so 'print end' is reached.
|
||||
# Ref.: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html
|
||||
# Left out are 'command exec /dev/null/nonexistent', where no shell follows the standard,
|
||||
# as well as 'command exit' and 'command return', because, well, obviously.
|
||||
command : </dev/null/no || print -n ok1
|
||||
command . /dev/null/no || print -n ok2
|
||||
command set +o bad@option || print -n ok3
|
||||
command shift $(($# + 1)) || print -n ok4
|
||||
(unalias times; PATH=/dev/null; eval 'command times foo bar >/dev/null || print -n ok5')
|
||||
command trap foo bar baz quux || print -n ok6
|
||||
command unset v || print -n ok7
|
||||
command eval "(" || print -n ok8
|
||||
command export v=baz || print -n ok9
|
||||
command readonly v=bar || print -n ok10
|
||||
command break && print -n ok11 # 'break' and 'continue' are POSIXly allowed to quietly...
|
||||
command continue && print -n ok12 # ..."succeed" if they are used outside of a loop :-/
|
||||
print end)
|
||||
[[ $got == "$exp" ]] || err_exit "prefixing special builtin with 'command' does not stop it from exiting the shell on error" \
|
||||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
Loading…
Reference in a new issue