From 500757d78b63235b1cbc27762704a51d3c2bec38 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Sat, 20 Feb 2021 19:52:08 +0000 Subject: [PATCH] Error out on 'redirect >foo' inside ${ shared-state comsub; } The following caused an infinite loop: v=${ exec >/dev/tty; } v=${ redirect >/dev/tty; } Even the original authors didn't figure out how to 'exec >foo' or 'redirect >foo' inside a non-forking command substitution, so they fork it by calling sh_subfork(). If we delete that call, even normal command substitutions enter into that infinite loop. But of course a shared-state comsub can never fork as it would no longer share its state. Without a solution to make this work without forking, an error message is the only sensible thing left to do. src/cmd/ksh93/sh/io.c: sh_redirect(): - If we're redirecting standard output (1), the redirection is permanent as in 'exec'/'redirect' (flag==2), and we're in a subshare, then error out. Resolves: https://github.com/ksh93/ksh/issues/128 --- src/cmd/ksh93/sh/io.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cmd/ksh93/sh/io.c b/src/cmd/ksh93/sh/io.c index 8cbc987ca..9071a9d0f 100644 --- a/src/cmd/ksh93/sh/io.c +++ b/src/cmd/ksh93/sh/io.c @@ -1126,8 +1126,13 @@ int sh_redirect(Shell_t *shp,struct ionod *iop, int flag) { iof=iop->iofile; fn = (iof&IOUFD); - if(fn==1 && shp->subshell && !shp->subshare && (flag==2 || isstring)) - sh_subfork(); + if(fn==1) + { + if(shp->subshare && flag==2) + errormsg(SH_DICT,ERROR_exit(1),"cannot redirect stdout inside shared-state comsub"); + if(shp->subshell && (flag==2 || isstring)) + sh_subfork(); + } if(shp->redir0 && fn==0 && !(iof&IOMOV)) shp->redir0 = 2; io_op[0] = '0'+(iof&IOUFD);