[GHC] #7229: Detecting if a process was killed by a signal is impossible
GHC
ghc-devs at haskell.org
Mon Nov 11 22:28:07 UTC 2013
#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 hvr):
So, the implementation of the last proposal ammmounts to two simple
modifications:
a patch to `process`:
{{{#!diff
diff --git a/cbits/runProcess.c b/cbits/runProcess.c
index 3462cfc..3a6f2f3 100644
--- a/cbits/runProcess.c
+++ b/cbits/runProcess.c
@@ -22,12 +22,12 @@
UNIX versions
-------------------------------------------------------------------------
*/
-//
-// If a process terminates with a signal, the exit status we return to
-// via the System.Process API follows the Unix shell convention of
-// (128 + signal).
-//
-#define TERMSIG_STATUS(r) ((r) | 0x80)
+// If a process was terminated by a signal, the exit status we return
+// via the System.Process API is (signum << 8); this avoids collision
+// with normal process termination status codes, as according to
+// http://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html
+// WEXITSTATUS(s) returns an 8-bit value. See also #7229.
+#define TERMSIG_STATUS(r) (r << 8)
static long max_fd = 0;
}}}
...and a patch for `base` (provided by duncan):
{{{#!diff
diff --git a/GHC/TopHandler.lhs b/GHC/TopHandler.lhs
index 9e4bc07..b0c5d0d 100644
--- a/GHC/TopHandler.lhs
+++ b/GHC/TopHandler.lhs
@@ -180,7 +180,25 @@ 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:
+-- high 7 bits signal, low 8 bits normal exit code.
+-- People can also use ExitCode that do not correspond to Unix exit()
+-- codes and we just use a replacement.
+safeExit r
+ | sig /= 0 && code == 0 && other == 0
+ = unsafeCoerce# (shutdownHaskellAndSignal $ fromIntegral sig)
+ | sig == 0 && other == 0
+ = unsafeCoerce# (shutdownHaskellAndExit $ fromIntegral code)
+ | otherwise
+ = unsafeCoerce# (shutdownHaskellAndExit 0xff)
+ where
+ sig = (r .&. 0x7f00) `shiftR` 8
+ code = r .&. 0x00ff
+ other = r .&. (complement 0x7fff)
+#endif
}}}
If there are no objections left, I'll apply the changes above, `validate`
(tweaking the testsuite if necessary) and push the changes.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/7229#comment:29>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list