1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-15 04:32:24 +00:00

Fix fork after redirecting stdout in subshare (re: 500757d7)

Previously, command substitutions executed as virtual subshells
were always forked if any command was run within them that
redireceted standard output, even if the redirection was local to
that command.

Commit 500757d7 removed the check for a shared-state command
substitution (subshare), so introduced a bug where even that would
fork, causing it to stop sharing its state.

We can further improve on that fix by only forking if the
redirection is permanent as with `exec` or `redirect`. There should
be no need to do that if the redirection is local to a command run
within the command substitution, as the file descriptor is restored
when that command finishes, which is still within the command
substitution.

src/cmd/ksh93/sh/io.c: sh_redirect():
- Only fork upon redirecting stdout if the virtual subshell is a
  command substitution, and if the redirection is permanent
  (flag==1 or flag==2).
This commit is contained in:
Martijn Dekker 2021-04-26 18:09:36 +01:00
parent 2aad3cab06
commit 090b65e79b
4 changed files with 22 additions and 6 deletions

6
NEWS
View file

@ -3,6 +3,12 @@ For full details, see the git log at: https://github.com/ksh93/ksh
Any uppercase BUG_* names are modernish shell bug IDs.
2021-04-26:
- Fixed a bug introduced on 2021-02-20 in which a shared-state command
substitution stopped sharing its state with the calling shell environment
if it executed a command that locally redirected standard outpuut.
2021-04-22:
- shcomp (the shell bytecode compiler) was fixed to correctly compile process

View file

@ -21,7 +21,7 @@
#define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */
#define SH_RELEASE_SVER "1.0.0-alpha" /* semantic version number: https://semver.org */
#define SH_RELEASE_DATE "2021-04-22" /* must be in this format for $((.sh.version)) */
#define SH_RELEASE_DATE "2021-04-26" /* must be in this format for $((.sh.version)) */
#define SH_RELEASE_CPYR "(c) 2020-2021 Contributors to ksh " SH_RELEASE_FORK
/* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */

View file

@ -1147,13 +1147,15 @@ int sh_redirect(Shell_t *shp,struct ionod *iop, int flag)
fn = (iof&IOUFD);
if(fn==1)
{
if(shp->subshare && flag==2)
if(shp->subshell && shp->comsub && (flag==1 || flag==2))
{
errormsg(SH_DICT,ERROR_exit(1),"cannot redirect stdout inside shared-state comsub");
UNREACHABLE();
}
if(shp->subshell && (flag==2 || isstring))
if(shp->subshare)
{
errormsg(SH_DICT,ERROR_exit(1),"cannot redirect stdout inside shared-state comsub");
UNREACHABLE();
}
sh_subfork();
}
}
if(shp->redir0 && fn==0 && !(iof&IOMOV))
shp->redir0 = 2;

View file

@ -1010,5 +1010,13 @@ unalias a
[[ $got == "$exp" ]] || err_exit 'backtick comsub with alias:' \
"expected $(printf %q "$exp"), got $(printf %q "$got")"
# ======
# Redirecting standard output for a single command should not cause a subshare to fork
exp='good'
got='bad'
dummy=${ : >&2; got='good'; }
[[ $got == "$exp" ]] || err_exit 'subshare stopped sharing state after command that redirects stdout' \
"(expected '$exp', got '$got')"
# ======
exit $((Errors<125?Errors:125))