1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Fix command substitutions in here-docs (rhbz#994241, rhbz#1036802)

When ksh was compiled with SHOPT_SPAWN (the default), any command
substitution embedded in a here-document returned an empty string.
The bug was also present in 93u+ 2012-08-01 (although not in every
case as some systems compile it without SHOPT_SPAWN).

This fixes it by applying a slightly edited combination of two Red
Hat patches (the second containing a fix for the first), which
backport a new command substitution mechanism from the abandoned
ksh 93v- beta version. The originals are:

642af4d6/f/ksh-20120801-macro.patch
642af4d6/f/ksh-20120801-fd2lost.patch

src/cmd/ksh93/include/io.h:
- The iopipe() function from xec.c is now needed in sh_subshell()
  (subshell.c), so rename it to sh_iounpipe() and declare it as an
  extern here. The 93v- beta did it as well. (The Red Hat patch did
  this without renaming it.)

src/cmd/ksh93/sh/xec.c:
- Backport new versions of iousepipe() and sh_iounpipe() from ksh
  93v-. New 'type' flaggery is introduced to distinguish between
  different command substitution conditions. What all that means
  remains to be determined.
- sh_exec(): I made one change to the Red Hat patch myself: if in a
  subshell and the type flags FAMP (for "ampersand" as in '&' as in
  background job) and TFORK are set, continue to call sh_subfork()
  to fork the subshell unconditionally, instead of only if we're in
  a command substitution connected to an unseekable file. Maybe the
  latter works for the 93v- code, but on 93u+(m) it causes a couple
  of regressions, which are fixed by my change:
  signal.sh[273]: subshell ignoring signal does not send signal to parent
  signal.sh[276]: subshell catching signal does not send signal to parent
  Details: https://github.com/ksh93/ksh/issues/104#issuecomment-696341902

src/cmd/ksh93/sh/macro.c,
src/cmd/ksh93/sh/subshell.c:
- Updates that go with those new functions.

Fixes:   https://github.com/ksh93/ksh/issues/104
Affects: https://github.com/ksh93/ksh/issues/124
This commit is contained in:
Martijn Dekker 2020-09-21 23:02:08 +02:00
parent 0d3bedd67d
commit 970069a6fe
6 changed files with 111 additions and 30 deletions

View file

@ -123,7 +123,8 @@ void sh_subtmpfile(Shell_t *shp)
else if(errno!=EBADF)
errormsg(SH_DICT,ERROR_system(1),e_toomany);
/* popping a discipline forces a /tmp file create */
sfdisc(sfstdout,SF_POPDISC);
if(shp->comsub != 1)
sfdisc(sfstdout,SF_POPDISC);
if((fd=sffileno(sfstdout))<0)
{
/* unable to create the /tmp file so use a pipe */
@ -173,6 +174,7 @@ void sh_subfork(void)
register struct subshell *sp = subshell_data;
Shell_t *shp = sp->shp;
unsigned int curenv = shp->curenv;
char comsub = shp->comsub;
pid_t pid;
char *trap = shp->st.trapcom[0];
if(trap)
@ -204,7 +206,7 @@ void sh_subfork(void)
shp->subshell = 0;
shp->comsub = 0;
sp->subpid=0;
shp->st.trapcom[0] = trap;
shp->st.trapcom[0] = (comsub==2 ? NULL : trap);
shp->savesig = 0;
/* sh_fork() increases ${.sh.subshell} but we forked an existing virtual subshell, so undo */
SH_SUBSHELLNOD->nvalue.s--;
@ -653,6 +655,13 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
}
else
{
if(comsub!=1 && shp->spid)
{
job_wait(shp->spid);
if(shp->pipepid==shp->spid)
shp->spid = 0;
shp->pipepid = 0;
}
/* move tmp file to iop and restore sfstdout */
iop = sfswap(sfstdout,NIL(Sfio_t*));
if(!iop)
@ -761,7 +770,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
shp->coutpipe = sp->coutpipe;
}
shp->subshare = sp->subshare;
shp->comsub = sp->comsub;
shp->subdup = sp->subdup;
if(shp->subshell)
{
@ -790,7 +798,12 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
if(nsig>0)
kill(getpid(),nsig);
if(sp->subpid)
{
job_wait(sp->subpid);
if(comsub>1)
sh_iounpipe(shp);
}
shp->comsub = sp->comsub;
if(comsub && iop && sp->pipefd<0)
sfseek(iop,(off_t)0,SEEK_SET);
if(shp->trapnote)