mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix process substitution combined with redirection (#40)
The code for handling process substitution with redirection was never being run because IORAW is usually set when IOPROCSUB is set. This commit fixes the problem by moving the required code out of the !IORAW if statement. The following command now prints 'good' instead of writing 'ok' to a bizzare file: $ ksh -c 'echo ok > >(sed s/ok/good/); wait' good This commit also fixes a bug that caused the process ID of the asynchronous process to print when the shell was in interactive mode. The following command no longer prints a process ID, behaving like in Bash and zsh: $ echo >(true) /dev/fd/5 src/cmd/ksh93/sh/args.c: - Temporarily turn off the interactive state while in a process substitution to prevent the shell from printing the PID of the asynchronous process. src/cmd/ksh93/sh/io.c: - Move the code for process substitution with redirection into a separate if statement. src/cmd/ksh93/tests/io.sh: - Add two tests for both process substitution bugs fixed by this commit. src/cmd/ksh93/tests/shtests: - Update shtests with a patch from Martijn Dekker to use pretty-printing for the output from the times builtin (if it is available). Fixes #2
This commit is contained in:
parent
1463236142
commit
0aa9e03f55
6 changed files with 88 additions and 46 deletions
|
@ -784,7 +784,7 @@ struct argnod *sh_argprocsub(Shell_t *shp,struct argnod *argp)
|
|||
{
|
||||
/* argument of the form <(cmd) or >(cmd) */
|
||||
register struct argnod *ap;
|
||||
int monitor, fd, pv[3];
|
||||
int monitor, interactive, fd, pv[3];
|
||||
int subshell = shp->subshell;
|
||||
ap = (struct argnod*)stkseek(shp->stk,ARGVAL);
|
||||
ap->argflag |= ARG_MAKE;
|
||||
|
@ -805,8 +805,14 @@ struct argnod *sh_argprocsub(Shell_t *shp,struct argnod *argp)
|
|||
sfputr(shp->stk,fmtbase((long)pv[fd],10,0),0);
|
||||
ap = (struct argnod*)stkfreeze(shp->stk,0);
|
||||
shp->inpipe = shp->outpipe = 0;
|
||||
|
||||
/* turn off job control */
|
||||
if(interactive = (sh_isstate(SH_INTERACTIVE)!=0))
|
||||
sh_offstate(SH_INTERACTIVE);
|
||||
if(monitor = (sh_isstate(SH_MONITOR)!=0))
|
||||
sh_offstate(SH_MONITOR);
|
||||
|
||||
/* do the process substitution */
|
||||
shp->subshell = 0;
|
||||
if(fd)
|
||||
{
|
||||
|
@ -818,9 +824,13 @@ struct argnod *sh_argprocsub(Shell_t *shp,struct argnod *argp)
|
|||
shp->outpipe = pv;
|
||||
sh_exec((Shnode_t*)argp->argchn.ap,(int)sh_isstate(SH_ERREXIT));
|
||||
}
|
||||
|
||||
/* restore the previous state */
|
||||
shp->subshell = subshell;
|
||||
if(monitor)
|
||||
sh_onstate(SH_MONITOR);
|
||||
if(interactive)
|
||||
sh_onstate(SH_INTERACTIVE);
|
||||
#if SHOPT_DEVFD
|
||||
close(pv[1-fd]);
|
||||
sh_iosave(shp,-pv[fd], shp->topfd, (char*)0);
|
||||
|
|
|
@ -1182,21 +1182,21 @@ int sh_redirect(Shell_t *shp,struct ionod *iop, int flag)
|
|||
strcpy(ap->argval,iop->ioname);
|
||||
fname=sh_macpat(shp,ap,(iof&IOARITH)?ARG_ARITH:ARG_EXP);
|
||||
}
|
||||
else if(iof&IOPROCSUB)
|
||||
{
|
||||
struct argnod *ap = (struct argnod*)stakalloc(ARGVAL+strlen(iop->ioname));
|
||||
memset(ap, 0, ARGVAL);
|
||||
if(iof&IOPUT)
|
||||
ap->argflag = ARG_RAW;
|
||||
else if(shp->subshell)
|
||||
sh_subtmpfile(shp);
|
||||
ap->argchn.ap = (struct argnod*)fname;
|
||||
ap = sh_argprocsub(shp,ap);
|
||||
fname = ap->argval;
|
||||
}
|
||||
else
|
||||
else if(!(iof&IOPROCSUB))
|
||||
fname=sh_mactrim(shp,fname,(!sh_isoption(SH_NOGLOB)&&sh_isoption(SH_INTERACTIVE))?2:0);
|
||||
}
|
||||
if((iof&IOPROCSUB) && !(iof&IOLSEEK))
|
||||
{
|
||||
struct argnod *ap = (struct argnod*)stakalloc(ARGVAL+strlen(iop->ioname));
|
||||
memset(ap, 0, ARGVAL);
|
||||
if(iof&IOPUT)
|
||||
ap->argflag = ARG_RAW;
|
||||
else if(shp->subshell)
|
||||
sh_subtmpfile(shp);
|
||||
ap->argchn.ap = (struct argnod*)fname;
|
||||
ap = sh_argprocsub(shp,ap);
|
||||
fname = ap->argval;
|
||||
}
|
||||
errno=0;
|
||||
np = 0;
|
||||
#if SHOPT_COSHELL
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue