From 70f6d758c0f2fda90bc3d49331397ffd62dca3af Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Thu, 30 Jul 2020 01:22:11 +0100 Subject: [PATCH] Fix blocked signals after fork(2)ing external command in subshell When the classic fork/exec mechanism was used (via sh_fork()) to run an external command from within a non-forking subshell, SIGINT was blocked until that subshell was exited. If a subsequent loop was run in the subshell, it became uninterruptible, e.g.: $ arch/*/bin/ksh -c '(/usr/bin/true; while :; do :; done); exit' ^C^C^C^C^C src/cmd/ksh93/sh/xec.c: - sh_fork() did not reset the savesig variable in the parent part of the fork when running in a virtual subshell. This had the effect of delaying signal handling until exiting the subshell. There is no reason for that subshell check that I can discern, so this removes it. I've verified that this causes no regression test failures even when ksh is compiled with -DSHOPT_SPAWN=0 which means the classic fork/exec mechanism is always used. Fixes: https://github.com/ksh93/ksh/issues/86 --- NEWS | 6 ++++++ src/cmd/ksh93/include/version.h | 2 +- src/cmd/ksh93/sh/xec.c | 11 ++++------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 608ef1986..77e8d560f 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,12 @@ For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. +2020-07-29: + +- On a ksh compiled to use fork(2) to run external commands, a bug has been + fixed that caused signals (such as SIGINT, Ctrl+C) to be ignored within a + non-forked subshell after running an external command within that subshell. + 2020-07-25: - Fixed BUG_MULTIBIFS: Multibyte characters can now be used as IFS diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 066f85373..eb535a6dd 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -17,4 +17,4 @@ * David Korn * * * ***********************************************************************/ -#define SH_RELEASE "93u+m 2020-07-25" +#define SH_RELEASE "93u+m 2020-07-29" diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index a6ad50747..baa8d6d12 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -2951,13 +2951,10 @@ pid_t sh_fork(Shell_t *shp,int flags, int *jobid) shp->savesig = -1; while(_sh_fork(shp,parent=fork(),flags,jobid) < 0); sh_stats(STAT_FORKS); - if(!shp->subshell) - { - sig = shp->savesig; - shp->savesig = 0; - if(sig>0) - kill(getpid(),sig); - } + sig = shp->savesig; + shp->savesig = 0; + if(sig>0) + kill(getpid(),sig); job_fork(parent); return(parent); }