From 523b7c70177a2d42b3bca7ca5ebd6a0ec3fbbd8d Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Sun, 24 Jul 2022 06:09:59 +0200 Subject: [PATCH] Part revert 39e467da 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] --- src/cmd/ksh93/sh/args.c | 2 +- src/cmd/ksh93/sh/io.c | 4 ++-- src/cmd/ksh93/sh/xec.c | 6 +++--- src/cmd/ksh93/tests/subshell.sh | 7 +++++++ 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/cmd/ksh93/sh/args.c b/src/cmd/ksh93/sh/args.c index faee9c45d..18c76efe6 100644 --- a/src/cmd/ksh93/sh/args.c +++ b/src/cmd/ksh93/sh/args.c @@ -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); diff --git a/src/cmd/ksh93/sh/io.c b/src/cmd/ksh93/sh/io.c index 10001806d..5bc48e9dc 100644 --- a/src/cmd/ksh93/sh/io.c +++ b/src/cmd/ksh93/sh/io.c @@ -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); } diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index 70e0dba7d..9fed172a0 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -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; diff --git a/src/cmd/ksh93/tests/subshell.sh b/src/cmd/ksh93/tests/subshell.sh index 1a8da97cc..402d083b2 100755 --- a/src/cmd/ksh93/tests/subshell.sh +++ b/src/cmd/ksh93/tests/subshell.sh @@ -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))