diff --git a/src/cmd/ksh93/sh/subshell.c b/src/cmd/ksh93/sh/subshell.c index a199e3c37..efc6ce525 100644 --- a/src/cmd/ksh93/sh/subshell.c +++ b/src/cmd/ksh93/sh/subshell.c @@ -549,14 +549,14 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) sp->options = shp->options; sp->jobs = job_subsave(); sp->subdup = shp->subdup; + shp->subdup = 0; /* make sure initialization has occurred */ if(!shp->pathlist) { shp->pathinit = 1; - path_get(shp,"."); + path_get(shp,e_dot); shp->pathinit = 0; } - sp->pathlist = path_dup((Pathcomp_t*)shp->pathlist); #if _lib_fchdir sp->pwdfd = -1; #endif /* _lib_fchdir */ @@ -570,6 +570,8 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) sp->subshare = shp->subshare; sp->comsub = shp->comsub; shp->subshare = comsub==2; + if(!shp->subshare) + sp->pathlist = path_dup((Pathcomp_t*)shp->pathlist); if(comsub) { shp->comsub = comsub; @@ -590,7 +592,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) } if(sp->pwdfd<0) { - int n = open(".",O_SEARCH); + int n = open(e_dot,O_SEARCH); if(n>=0) { sp->pwdfd = n; @@ -759,11 +761,16 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) } sfset(iop,SF_READ,1); } - sfswap(sp->saveout,sfstdout); + if(sp->saveout) + sfswap(sp->saveout,sfstdout); + else + sfstdout = &_Sfstdout; /* check if standard output was preserved */ if(sp->tmpfd>=0) { - close(1); + int err=errno; + while(close(1)<0 && errno==EINTR) + errno = err; if (fcntl(sp->tmpfd,F_DUPFD,1) != 1) { saveerrno = errno; @@ -773,8 +780,11 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) } shp->fdstatus[1] = sp->fdstatus; } - path_delete((Pathcomp_t*)shp->pathlist); - shp->pathlist = (void*)sp->pathlist; + if(!shp->subshare) + { + path_delete((Pathcomp_t*)shp->pathlist); + shp->pathlist = (void*)sp->pathlist; + } job_subrestore(sp->jobs); shp->curenv = shp->jobenv = savecurenv; job.curpgid = savejobpgid; diff --git a/src/cmd/ksh93/tests/path.sh b/src/cmd/ksh93/tests/path.sh index 2a455f1df..f24ad42d2 100755 --- a/src/cmd/ksh93/tests/path.sh +++ b/src/cmd/ksh93/tests/path.sh @@ -731,6 +731,15 @@ got=$({ FPATH=$tmp/fun.$$ "$SHELL" -c self; } 2>&1) (((e = $?) == 126)) || err_exit 'Function autoload recursion loop:' \ "got status $e$( ((e>128)) && print -n / && kill -l "$e"), $(printf %q "$got")" +# ====== +# If a shared-state ${ command substitution; } changed the value of $PATH, the variable +# would change but the internal pathlist would not, making path searches inconsistent. +savePATH=$PATH +got=${ PATH=/dev/null; } +got=$(whence ls) +PATH=$savePATH +[[ -z $got ]] || err_exit "PATH search inconsistent after changing PATH in subshare (got $(printf %q "$got"))" + # ====== exit $((Errors<125?Errors:125))