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:
parent
b2a7ec032f
commit
0cd8646361
4 changed files with 25 additions and 6 deletions
4
NEWS
4
NEWS
|
@ -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
|
||||
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:
|
||||
|
||||
- Fixed a regression, introduced in ksh 93t+ 2009-07-31, that caused a command
|
||||
|
|
6
TODO
6
TODO
|
@ -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
|
||||
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
|
||||
substitution with # and %), if IFS starts with ? or * and the "$*"
|
||||
parameter expansion inserts any IFS separator characters, those characters
|
||||
|
|
|
@ -755,6 +755,7 @@ onintr(struct addrinfo* addr, void* handle)
|
|||
int sh_open(register const char *path, int flags, ...)
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
Sfio_t *sp;
|
||||
register int fd = -1;
|
||||
mode_t mode;
|
||||
char *e;
|
||||
|
@ -869,6 +870,16 @@ int sh_open(register const char *path, int flags, ...)
|
|||
mode = IOREAD;
|
||||
if(fd >= shp->gd->lim.open_max)
|
||||
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;
|
||||
return(fd);
|
||||
}
|
||||
|
|
|
@ -785,5 +785,15 @@ then
|
|||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
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))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue