1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00
Even tough sh_subtmpfile() should only be relevant to command
substitutions, checking the sh.comsub flag instead of sh.subshell
before calling is not valid in all cases; subshells of command
substitutions run into problems in some oddly specific cases, e.g.,
both 'eval' and an external command must be involved. The ksh
regression tests didn't detect a problem, but both modernish[*] and
shellspec[*] have one regression test failure after that change.

Minimal reproducer, assuming a cat at /bin/cat:

    v=$(eval 'print output | /bin/cat')
    print -r "v=[$v]"

Actual output:

    output
    v=[]

Expected output:

    v=[output]
This commit is contained in:
Martijn Dekker 2022-07-24 06:09:59 +02:00
parent bb4f23e63f
commit 523b7c7017
4 changed files with 13 additions and 6 deletions

View file

@ -721,7 +721,7 @@ struct argnod *sh_argprocsub(struct argnod *argp)
ap->argflag |= ARG_MAKE;
ap->argflag &= ~ARG_RAW;
fd = argp->argflag&ARG_RAW;
if(fd==0 && sh.comsub)
if(fd==0 && sh.subshell)
sh_subtmpfile();
#if SHOPT_DEVFD
sfwrite(sh.stk,e_devfdNN,8);

View file

@ -1173,7 +1173,7 @@ int sh_redirect(struct ionod *iop, int flag)
memset(ap, 0, ARGVAL);
if(iof&IOPUT)
ap->argflag = ARG_RAW;
else if(sh.comsub)
else if(sh.subshell)
sh_subtmpfile();
ap->argchn.ap = (struct argnod*)fname;
ap = sh_argprocsub(ap);
@ -1241,7 +1241,7 @@ int sh_redirect(struct ionod *iop, int flag)
}
if(sh.subshell && dupfd==1)
{
if(sh.comsub)
if(sh.subshell)
sh_subtmpfile();
dupfd = sffileno(sfstdout);
}

View file

@ -1245,7 +1245,7 @@ int sh_exec(register const Shnode_t *t, int flags)
bp->sigset = 0;
bp->notify = 0;
bp->flags = (OPTIMIZE!=0);
if(sh.comsub && nv_isattr(np,BLT_NOSFIO))
if(sh.subshell && nv_isattr(np,BLT_NOSFIO))
sh_subtmpfile();
if(argn)
sh.exitval = (*sh.bltinfun)(argn,com,(void*)bp);
@ -1445,7 +1445,7 @@ int sh_exec(register const Shnode_t *t, int flags)
register pid_t parent;
int no_fork,jobid;
int pipes[3];
if(sh.comsub)
if(sh.subshell)
sh_subtmpfile();
if(no_fork = check_exec_optimization(type,execflg,execflg2,t->fork.forkio))
job.parent=parent=0;
@ -1823,7 +1823,7 @@ int sh_exec(register const Shnode_t *t, int flags)
echeck = 1;
job.exitval = 0;
job.curjobid = 0;
if(sh.comsub)
if(sh.subshell)
sh_subtmpfile();
sh.inpipe = pvo;
sh.outpipe = pvn;

View file

@ -1178,5 +1178,12 @@ exp=OK
[[ $got == "$exp" ]] || err_exit 'trap ignored when signalled from a subshell that is the last command' \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# ======
# if this fails with empty output, sh_subtmpfile() is not getting called where it should be
exp='some output'
{ got=$(eval 'print -r -- "$exp" | "$bincat"'); } >/dev/null
[[ $got == "$exp" ]] || err_exit 'command substitution did not catch output' \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# ======
exit $((Errors<125?Errors:125))