
#7229: Detecting if a process was killed by a signal is impossible --------------------------------------+------------------------------------ Reporter: benmachine | Owner: Type: bug | Status: new Priority: high | Milestone: 7.8.1 Component: libraries/process | Version: Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: --------------------------------------+------------------------------------ Comment (by duncan): Here's my updated patch. '''Totally untested''' {{{#!diff diff --git a/GHC/TopHandler.lhs b/GHC/TopHandler.lhs index 9e4bc07..8953334 100644 --- a/GHC/TopHandler.lhs +++ b/GHC/TopHandler.lhs @@ -180,7 +180,28 @@ flushStdHandles = do -- we have to use unsafeCoerce# to get the 'IO a' result type, since the -- compiler doesn't let us declare that as the result type of a foreign export. safeExit :: Int -> IO a +#ifdef mingw32_HOST_OS safeExit r = unsafeCoerce# (shutdownHaskellAndExit $ fromIntegral r) +#else +-- On Unix we use an encoding for the ExitCode: +-- Bits: 0-7 (mask 0x00ff) normal exit code +-- Bits: 8-14 (mask 0x7f00) exit by signal +-- Bits: 15 (mask 0x8000) core dump (allowed with signal but ignored) +-- A normal exit, and exit by signal are mutually exclusive. +-- For any invalid encoding we just use a replacement (0xff). +safeExit r + | sig /= 0 && code == 0 && other == 0 {-any cdump-} + = unsafeCoerce# (shutdownHaskellAndSignal $ fromIntegral sig) + | sig == 0 {-any code-} && other == 0 && cdump == 0 + = unsafeCoerce# (shutdownHaskellAndExit $ fromIntegral code) + | otherwise + = unsafeCoerce# (shutdownHaskellAndExit 0xff) + where + sig = (r .&. 0x7f00) `shiftR` 8 + cdump = r .&. 0x8000 + code = r .&. 0x00ff + other = r .&. (complement 0xffff) +#endif exitInterrupted :: IO a exitInterrupted = }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/7229#comment:35 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler