hndStdInput <- fdToHandle pfdStdInput WriteMode
hndStdOutput <- fdToHandle pfdStdOutput ReadMode
hndStdError <- fdToHandle pfdStdError ReadMode
- return (hndStdInput, hndStdOutput, hndStdError, ProcessHandle proc_handle)
+ ph <- mkProcessHandle proc_handle
+ return (hndStdInput, hndStdOutput, hndStdError, ph)
foreign import ccall unsafe "runInteractiveProcess"
c_runInteractiveProcess
hndStdInput <- fdToHandle pfdStdInput WriteMode
hndStdOutput <- fdToHandle pfdStdOutput ReadMode
hndStdError <- fdToHandle pfdStdError ReadMode
- return (hndStdInput, hndStdOutput, hndStdError,
- ProcessHandle proc_handle)
+ ph <- mkProcessHandle proc_handle
+ return (hndStdInput, hndStdOutput, hndStdError, ph)
foreign import ccall unsafe "runInteractiveProcess"
c_runInteractiveProcess
waitForProcess
:: ProcessHandle
-> IO ExitCode
-waitForProcess (ProcessHandle handle) = do
+waitForProcess ph = do
+ handle <- getProcessHandle ph
code <- throwErrnoIfMinus1 "waitForProcess" (c_waitForProcess handle)
if (code == 0)
then return ExitSuccess
-- On Windows systems, the Win32 @TerminateProcess@ function is called, passing
-- an exit code of 1.
terminateProcess :: ProcessHandle -> IO ()
-terminateProcess (ProcessHandle pid) =
+terminateProcess ph = do
+ pid <- getProcessHandle ph
throwErrnoIfMinus1_ "terminateProcess" (c_terminateProcess pid)
-- ----------------------------------------------------------------------------
'ExitSuccess'@, regardless of what the original exit code was.
-}
getProcessExitCode :: ProcessHandle -> IO (Maybe ExitCode)
-getProcessExitCode (ProcessHandle handle) =
+getProcessExitCode ph = do
+ handle <- getProcessHandle ph
alloca $ \pExitCode -> do
res <- throwErrnoIfMinus1 "getProcessExitCode" (c_getProcessExitCode handle pExitCode)
code <- peek pExitCode
-- #hide
module System.Process.Internals (
- ProcessHandle(..), PHANDLE,
+ ProcessHandle(..), PHANDLE, getProcessHandle, mkProcessHandle,
#if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
pPrPr_disableITimers, c_execvpe,
# ifdef __GLASGOW_HASKELL__
import System.IO ( Handle )
#else
import Data.Word ( Word32 )
+import Data.IORef
#endif
import Data.Maybe ( fromMaybe )
to wait for the process later.
-}
#if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
+
type PHANDLE = CPid
+newtype ProcessHandle = ProcessHandle PHANDLE
+
+getProcessHandle :: ProcessHandle -> IO PHANDLE
+getProcessHandle (ProcessHandle p) = return p
+
+mkProcessHandle :: PHANDLE -> IO ProcessHandle
+mkProcessHandle p = return (ProcessHandle p)
+
#else
+
type PHANDLE = Word32
+newtype ProcessHandle = ProcessHandle (IORef PHANDLE)
+
+getProcessHandle :: ProcessHandle -> IO PHANDLE
+getProcessHandle (ProcessHandle ior) = readIORef ior
+
+-- On Windows, we have to close this HANDLE when it is no longer required,
+-- hence we add a finalizer to it, using an IORef as the box on which to
+-- attach the finalizer.
+mkProcessHandle :: PHANDLE -> IO ProcessHandle
+mkProcessHandle h = do
+ ioref <- newIORef h
+ mkWeakIORef ioref (c_CloseHandle h)
+ return (ProcessHandle ioref)
+
+foreign import stdcall unsafe "CloseHandle"
+ c_CloseHandle
+ :: PHANDLE
+ -> IO ()
#endif
-newtype ProcessHandle = ProcessHandle PHANDLE
-
-- ----------------------------------------------------------------------------
#if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
c_runProcess pargs pWorkDir pEnv
fd_stdin fd_stdout fd_stderr
set_int inthand set_quit quithand
- return (ProcessHandle ph)
+ mkProcessHandle ph
foreign import ccall unsafe "runProcess"
c_runProcess
proc_handle <- throwErrnoIfMinus1 fun
(c_runProcess pcmdline pWorkDir pEnv
fd_stdin fd_stdout fd_stderr)
- return (ProcessHandle proc_handle)
+ mkProcessHandle proc_handle
foreign import ccall unsafe "runProcess"
c_runProcess