1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Backport bugfix for BUG_CSUBSTDO from ksh93v- 2012-08-24 (#259)

This commit fixes BUG_CSUBSTDO, which could break stdout inside of
non-forking command substitutions. The breakage only occurred when
stdout was closed outside of the command substitution and a file
descriptor other than stdout was redirected in the command substitution
(such as stderr). Thanks to the ast-open-history repo, I was able to
identify and backport the bugfix from ksh93v- 2012-08-24.

This backport may fix other bugs as well. On 93v- 2012-08-24 it
fixed the regression below, though it was not triggered on 93u+(m).
  src/cmd/ksh93/tests/heredoc.sh
  487 print foo > $tmp/foofile 
  488 x=$( $SHELL 2> /dev/null 'read <<< $(<'"$tmp"'/foofile) 2> /dev/null;print -r "$REPLY"') 
  489 [[ $x == foo ]] || err_exit '<<< $(<file) not working' 

src/cmd/ksh93/sh/io.c: sh_open():
- If the just-opened file descriptor exists in sftable and is
  flagged with SF_STRING (as in non-forking command substitutions,
  among other situations), then move the file descriptor to a
  number >= 10.

src/cmd/ksh93/tests/io.sh:
- Add a regression test for BUG_CSUBSTDO, adapted from the one in
  modernish.
This commit is contained in:
Johnothan King 2021-04-08 05:24:17 -07:00 committed by GitHub
parent b2a7ec032f
commit 0cd8646361
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 6 deletions

4
NEWS
View file

@ -8,6 +8,10 @@ Any uppercase BUG_* names are modernish shell bug IDs.
- The $LC_TIME variable is now recognized by ksh and if set to an invalid - The $LC_TIME variable is now recognized by ksh and if set to an invalid
locale will show an error. locale will show an error.
- Fixed BUG_CSUBSTDO: If standard output is closed before running a command
substitution, redirecting any other file descriptor no longer closes standard
output inside of the command substitution.
2021-04-05: 2021-04-05:
- Fixed a regression, introduced in ksh 93t+ 2009-07-31, that caused a command - Fixed a regression, introduced in ksh 93t+ 2009-07-31, that caused a command

6
TODO
View file

@ -23,12 +23,6 @@ https://github.com/modernish/modernish/tree/0.16/lib/modernish/cap/
initial ! (and, on some shells, ^) retains the meaning of negation, even initial ! (and, on some shells, ^) retains the meaning of negation, even
in quoted strings within bracket patterns, including quoted variables. in quoted strings within bracket patterns, including quoted variables.
- BUG_CSUBSTDO: If standard output (file descriptor 1) is closed before
entering a $(command substitution), and any other file descriptors are
redirected within the command substitution, commands such as 'echo' will
not work within the command substitution, acting as if standard output is
still closed.
- BUG_IFSGLOBS: In glob pattern matching (as in case or parameter - BUG_IFSGLOBS: In glob pattern matching (as in case or parameter
substitution with # and %), if IFS starts with ? or * and the "$*" substitution with # and %), if IFS starts with ? or * and the "$*"
parameter expansion inserts any IFS separator characters, those characters parameter expansion inserts any IFS separator characters, those characters

View file

@ -755,6 +755,7 @@ onintr(struct addrinfo* addr, void* handle)
int sh_open(register const char *path, int flags, ...) int sh_open(register const char *path, int flags, ...)
{ {
Shell_t *shp = sh_getinterp(); Shell_t *shp = sh_getinterp();
Sfio_t *sp;
register int fd = -1; register int fd = -1;
mode_t mode; mode_t mode;
char *e; char *e;
@ -869,6 +870,16 @@ int sh_open(register const char *path, int flags, ...)
mode = IOREAD; mode = IOREAD;
if(fd >= shp->gd->lim.open_max) if(fd >= shp->gd->lim.open_max)
sh_iovalidfd(shp,fd); sh_iovalidfd(shp,fd);
if((sp = shp->sftable[fd]) && (sfset(sp,0,0) & SF_STRING))
{
int n,err=errno;
if((n = sh_fcntl(fd,F_DUPFD,10)) >= 10)
{
while(close(fd) < 0 && errno == EINTR)
errno = err;
fd = n;
}
}
shp->fdstatus[fd] = mode; shp->fdstatus[fd] = mode;
return(fd); return(fd);
} }

View file

@ -785,5 +785,15 @@ then
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))" "(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
fi fi
# ======
# Test for BUG_CSUBSTDO: If stdout is closed before running a command substitution,
# redirecting any file descriptor in the command substitution would break stdout
# inside of the command substitution. This only occurred when redirecting any other
# file descriptor inside of the command substitution.
exp='Foo bar'
{ got=$(echo 'Foo bar' 2>/dev/null); } >&-
[[ $exp == $got ]] || err_exit "BUG_CSUBSTDO: Closing stdout outside of command substitution breaks stdout inside of command substitution" \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# ====== # ======
exit $((Errors<125?Errors:125)) exit $((Errors<125?Errors:125))