Skip to content

Commit 7b6f469

Browse files
committed
Terminate child processes on sigINT/sigTERM etc
1 parent 4374c27 commit 7b6f469

File tree

3 files changed

+21
-4
lines changed

3 files changed

+21
-4
lines changed

Cabal/Cabal.cabal

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ library
4646
filepath >= 1.3.0.1 && < 1.5,
4747
pretty >= 1.1.1 && < 1.2,
4848
process >= 1.1.0.2 && < 1.7,
49-
time >= 1.4.0.1 && < 1.12
49+
time >= 1.4.0.1 && < 1.12,
50+
signal
5051

5152
if flag(bundled-binary-generic)
5253
build-depends: binary >= 0.5.1.1 && < 0.7

Cabal/src/Distribution/Compat/Process.hs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ module Distribution.Compat.Process (
66
rawSystem,
77
-- * Additions
88
enableProcessJobs,
9+
cleanUpProcessOnInterrupt,
910
) where
1011

12+
import Control.Monad (forM_)
1113
import System.Exit (ExitCode (..))
1214
import System.IO (Handle)
15+
import System.Signal
1316

1417
import System.Process (CreateProcess, ProcessHandle)
1518
import qualified System.Process as Process
@@ -54,13 +57,23 @@ createProcess = Process.createProcess . enableProcessJobs
5457
rawSystem :: String -> [String] -> IO ExitCode
5558
rawSystem cmd args = do
5659
#if MIN_VERSION_process(1,2,0)
57-
(_,_,_,p) <- createProcess (Process.proc cmd args) { Process.delegate_ctlc = True }
60+
pp@(_, _, _, p) <- createProcess (Process.proc cmd args) { Process.delegate_ctlc = True }
61+
cleanUpProcessOnInterrupt pp
5862
waitForProcess p
5963
#else
6064
-- With very old 'process', just do its rawSystem
6165
Process.rawSystem cmd args
6266
#endif
6367

68+
69+
-- | Installs signal handlers to clean up the process on interrupt of:
70+
-- - '[sigABRT, sigFPE, sigILL, sigINT, sigSEGV, sigTERM]'
71+
cleanUpProcessOnInterrupt :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> IO ()
72+
cleanUpProcessOnInterrupt (stdin, stdout, stderr, p) =
73+
forM_ [sigABRT, sigFPE, sigILL, sigINT, sigSEGV, sigTERM] $ \sig ->
74+
installHandler sig (\_ -> Process.cleanupProcess (stdin, stdout, stderr, p))
75+
76+
6477
-- | 'System.Process.runInteractiveProcess' with process jobs enabled when
6578
-- appropriate. See 'enableProcessJobs'.
6679
runInteractiveProcess

Cabal/src/Distribution/Simple/Utils.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ import qualified Control.Exception as Exception
237237
import Foreign.C.Error (Errno (..), ePIPE)
238238
import Data.Time.Clock.POSIX (getPOSIXTime, POSIXTime)
239239
import Numeric (showFFloat)
240-
import Distribution.Compat.Process (createProcess, rawSystem, runInteractiveProcess)
240+
import Distribution.Compat.Process (createProcess, rawSystem, runInteractiveProcess, cleanUpProcessOnInterrupt)
241241
import System.Process
242242
( ProcessHandle
243243
, showCommandForUser, waitForProcess)
@@ -800,8 +800,10 @@ rawSystemIOWithEnv :: Verbosity
800800
-> Maybe Handle -- ^ stderr
801801
-> IO ExitCode
802802
rawSystemIOWithEnv verbosity path args mcwd menv inp out err = withFrozenCallStack $ do
803-
(_,_,_,ph) <- createProcessWithEnv verbosity path args mcwd menv
803+
pp@(_,_,_,ph) <- createProcessWithEnv verbosity path args mcwd menv
804804
(mbToStd inp) (mbToStd out) (mbToStd err)
805+
cleanUpProcessOnInterrupt pp
806+
805807
exitcode <- waitForProcess ph
806808
unless (exitcode == ExitSuccess) $ do
807809
debug verbosity $ path ++ " returned " ++ show exitcode
@@ -897,6 +899,7 @@ rawSystemStdInOut verbosity path args mcwd menv input _ = withFrozenCallStack $
897899
(runInteractiveProcess path args mcwd menv)
898900
(\(inh,outh,errh,_) -> hClose inh >> hClose outh >> hClose errh)
899901
$ \(inh,outh,errh,pid) -> do
902+
cleanUpProcessOnInterrupt (Just inh,Just outh,Just errh,pid)
900903

901904
-- output mode depends on what the caller wants
902905
-- but the errors are always assumed to be text (in the current locale)

0 commit comments

Comments
 (0)