diff options
author | Simon Marlow <marlowsd@gmail.com> | 2009-02-19 10:05:32 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2009-02-19 10:05:32 +0000 |
commit | 1c4608e3b8737dbb9204f850af4d680ccea7d8ec (patch) | |
tree | 4b0a197cbf665b4f15f5c29b399edb5b16481c11 /System/Posix/Process.hsc | |
parent | cfd7c9a5bdcc7f7c414b408d19c8a39a2917eec8 (diff) |
Rewrite of signal-handling.
The API is the same (for now). The new implementation has the
capability to define signal handlers that have access to the siginfo
of the signal (#592), but this functionality is not exposed in this
patch.
#2451 is the ticket for the new API.
The main purpose of bringing this in now is to fix race conditions in
the old signal handling code (#2858). Later we can enable the new
API in the HEAD.
Implementation differences:
- More of the signal-handling is moved into Haskell. We store the
table of signal handlers in an MVar, rather than having a table of
StablePtrs in the RTS.
- In the threaded RTS, the siginfo of the signal is passed down the
pipe to the IO manager thread, which manages the business of
starting up new signal handler threads. In the non-threaded RTS,
the siginfo of caught signals is stored in the RTS, and the
scheduler starts new signal handler threads.
Diffstat (limited to 'System/Posix/Process.hsc')
-rw-r--r-- | System/Posix/Process.hsc | 55 |
1 files changed, 6 insertions, 49 deletions
diff --git a/System/Posix/Process.hsc b/System/Posix/Process.hsc index 71c286e..8e12739 100644 --- a/System/Posix/Process.hsc +++ b/System/Posix/Process.hsc @@ -72,12 +72,10 @@ import Foreign.Ptr ( Ptr, nullPtr ) import Foreign.StablePtr ( StablePtr, newStablePtr, freeStablePtr ) import Foreign.Storable ( Storable(..) ) import System.IO -import System.IO.Error import System.Exit import System.Posix.Error -import System.Posix.Process.Internals ( pPrPr_disableITimers, c_execvpe ) +import System.Posix.Process.Internals import System.Posix.Types -import System.Posix.Signals import Control.Monad #ifdef __GLASGOW_HASKELL__ @@ -316,11 +314,6 @@ foreign import ccall unsafe "execve" -- ----------------------------------------------------------------------------- -- Waiting for process termination -data ProcessStatus = Exited ExitCode - | Terminated Signal - | Stopped Signal - deriving (Eq, Ord, Show) - -- | @'getProcessStatus' blk stopped pid@ calls @waitpid@, returning -- @'Just' tc@, the 'ProcessStatus' for process @pid@ if it is -- available, 'Nothing' otherwise. If @blk@ is 'False', then @@ -334,7 +327,7 @@ getProcessStatus block stopped pid = (c_waitpid pid wstatp (waitOptions block stopped)) case pid' of 0 -> return Nothing - _ -> do ps <- decipherWaitStatus wstatp + _ -> do ps <- readWaitStatus wstatp return (Just ps) -- safe, because this call might block @@ -358,7 +351,7 @@ getGroupProcessStatus block stopped pgid = (c_waitpid (-pgid) wstatp (waitOptions block stopped)) case pid of 0 -> return Nothing - _ -> do ps <- decipherWaitStatus wstatp + _ -> do ps <- readWaitStatus wstatp return (Just (pid, ps)) -- | @'getAnyProcessStatus' blk stopped@ calls @waitpid@, returning -- @'Just' (pid, tc)@, the 'ProcessID' and 'ProcessStatus' for any @@ -378,46 +371,10 @@ waitOptions True True = (#const WUNTRACED) -- Turn a (ptr to a) wait status into a ProcessStatus -decipherWaitStatus :: Ptr CInt -> IO ProcessStatus -decipherWaitStatus wstatp = do +readWaitStatus :: Ptr CInt -> IO ProcessStatus +readWaitStatus wstatp = do wstat <- peek wstatp - if c_WIFEXITED wstat /= 0 - then do - let exitstatus = c_WEXITSTATUS wstat - if exitstatus == 0 - then return (Exited ExitSuccess) - else return (Exited (ExitFailure (fromIntegral exitstatus))) - else do - if c_WIFSIGNALED wstat /= 0 - then do - let termsig = c_WTERMSIG wstat - return (Terminated (fromIntegral termsig)) - else do - if c_WIFSTOPPED wstat /= 0 - then do - let stopsig = c_WSTOPSIG wstat - return (Stopped (fromIntegral stopsig)) - else do - ioError (mkIOError illegalOperationErrorType - "waitStatus" Nothing Nothing) - -foreign import ccall unsafe "__hsunix_wifexited" - c_WIFEXITED :: CInt -> CInt - -foreign import ccall unsafe "__hsunix_wexitstatus" - c_WEXITSTATUS :: CInt -> CInt - -foreign import ccall unsafe "__hsunix_wifsignaled" - c_WIFSIGNALED :: CInt -> CInt - -foreign import ccall unsafe "__hsunix_wtermsig" - c_WTERMSIG :: CInt -> CInt - -foreign import ccall unsafe "__hsunix_wifstopped" - c_WIFSTOPPED :: CInt -> CInt - -foreign import ccall unsafe "__hsunix_wstopsig" - c_WSTOPSIG :: CInt -> CInt + decipherWaitStatus wstat -- ----------------------------------------------------------------------------- -- Exiting |