From 4b22fd5d0f44fd54aa24f2d2aac13b3573601650 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Mon, 13 Jun 2022 23:34:46 +0100 Subject: [PATCH] rm bg job double-fork workaround (re: 50db00e1, ed9053ec, e3d7bf1d) $ ksh -c '(sleep 1 & echo ${.sh.stats.forks}); :' 2 The shell forks twice. A virtual subshell that launches a background job forks first before forking the background job. As discussed in the P.S. in e3d7bf1d, this is caused by the following code in sh_exec() in xec.c (as since changed in 4ce486a7, e40aaa8a, 88a1f3d6, and a2196f94): 1505: if((type&(FAMP|TFORK))==(FAMP|TFORK)) 1506: { 1507: if(sh.comsub && !(sh.fdstatus[1]&IONOSEEK)) 1508: unpipe = iousepipe(); 1509: if(!sh.subshare) 1510: sh_subfork(); 1511: } This smells like an ugly workaround. It forks a virtual subshell whenever a background job is launched within it, whether there is an actual reason to do this or not. Researching the ksh93-history repo reveals that this workaround had already gone through many different versions before we restarted ksh development. In the e3d7bf1d P.S. discussion, four regression test failures were caused by removing this workaround. I recently tried it again and two of the failures were already gone. (Testing which commits fix it would require recompiling every 93u+m commit with the workaround patched out and I can't be bothered.) Two were left: the two signal.sh failures. The last commit (50db00e1) fixed those as well. So I believe we no longer need this workaround, which never did make very much sense. Removing it significantly improves the performance of ksh when launching background jobs from subshells. --- src/cmd/ksh93/sh/xec.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index bfcbe40da..45db4bed6 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -1494,16 +1494,7 @@ int sh_exec(register const Shnode_t *t, int flags) int no_fork,jobid; int pipes[3]; if(sh.subshell) - { sh_subtmpfile(); - if((type&(FAMP|TFORK))==(FAMP|TFORK)) - { - if(sh.comsub && !(sh.fdstatus[1]&IONOSEEK)) - unpipe = iousepipe(); - if(!sh.subshare) - sh_subfork(); - } - } no_fork = !(type&(FAMP|FPOU)) && !sh.subshell && !(sh.st.trapcom[SIGINT] && *sh.st.trapcom[SIGINT])