diff options
Diffstat (limited to 'System/Posix/Process/Internals.hs')
-rw-r--r-- | System/Posix/Process/Internals.hs | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/System/Posix/Process/Internals.hs b/System/Posix/Process/Internals.hs index 8639819..deb1992 100644 --- a/System/Posix/Process/Internals.hs +++ b/System/Posix/Process/Internals.hs @@ -1,8 +1,20 @@ -module System.Posix.Process.Internals (pPrPr_disableITimers, c_execvpe) where +module System.Posix.Process.Internals ( + pPrPr_disableITimers, c_execvpe, + decipherWaitStatus, ProcessStatus(..) ) where import Foreign import Foreign.C +import System.Exit +import System.IO.Error +import GHC.Conc (Signal) + +-- we had to move this into GHC.Conc in GHC to avoid recursive dependencies. +-- it can be moved back when the signal handling stuff in base is moved out. +data ProcessStatus = Exited ExitCode + | Terminated Signal + | Stopped Signal + deriving (Eq, Ord, Show) -- this function disables the itimer, which would otherwise cause confusing -- signals to be sent to the new process. @@ -11,3 +23,44 @@ foreign import ccall unsafe "pPrPr_disableITimers" foreign import ccall unsafe "execvpe" c_execvpe :: CString -> Ptr CString -> Ptr CString -> IO CInt + +decipherWaitStatus :: CInt -> IO ProcessStatus +decipherWaitStatus wstat = + 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 + |