1 {-# OPTIONS_GHC -cpp -fffi #-}
2 -----------------------------------------------------------------------------
4 -- Module : System.Process
5 -- Copyright : (c) The University of Glasgow 2004
6 -- License : BSD-style (see the file libraries/base/LICENSE)
8 -- Maintainer : libraries@haskell.org
9 -- Stability : experimental
10 -- Portability : portable
12 -- Operations for creating and interacting with sub-processes.
14 -----------------------------------------------------------------------------
17 -- * Flag to control whether exiting the parent also kills the child.
18 -- * Windows impl of runProcess should close the Handles.
19 -- * Add system/rawSystem replacements
21 {- NOTES on createPipe:
23 createPipe is no longer exported, because of the following problems:
25 - it wasn't used to implement runInteractiveProcess on Unix, because
26 the file descriptors for the unused ends of the pipe need to be closed
29 - on Windows, a special version of createPipe is needed that sets
30 the inheritance flags correctly on the ends of the pipe (see
34 module System.Process (
35 -- * Running sub-processes
39 runInteractiveCommand,
40 runInteractiveProcess,
42 -- * Process completion
50 import System.Process.Internals
54 import System.IO ( IOMode(..), Handle, hClose )
55 import System.Exit ( ExitCode(..) )
57 import System.Posix.Internals
58 import GHC.IOBase ( FD )
59 import GHC.Handle ( openFd )
61 -- ----------------------------------------------------------------------------
64 {- | Runs a command using the shell.
70 runCommand string = do
71 (cmd,args) <- commandToProcess string
72 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
73 runProcessPosix "runCommand" cmd args Nothing Nothing Nothing Nothing Nothing
76 runProcessWin32 "runCommand" cmd [] Nothing Nothing Nothing Nothing Nothing args
79 -- ----------------------------------------------------------------------------
82 {- | Runs a raw command, optionally specifying 'Handle's from which to
83 take the @stdin@, @stdout@ and @stderr@ channels for the new
84 process (otherwise these handles are inherited from the current
87 Any 'Handle's passed to 'runProcess' are placed immediately in the
91 :: FilePath -- ^ Filename of the executable
92 -> [String] -- ^ Arguments to pass to the executable
93 -> Maybe FilePath -- ^ Optional path to the working directory
94 -> Maybe [(String,String)] -- ^ Optional environment (otherwise inherit)
95 -> Maybe Handle -- ^ Handle to use for @stdin@
96 -> Maybe Handle -- ^ Handle to use for @stdout@
97 -> Maybe Handle -- ^ Handle to use for @stderr@
100 runProcess cmd args mb_cwd mb_env mb_stdin mb_stdout mb_stderr = do
101 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
102 h <- runProcessPosix "runProcess" cmd args mb_cwd mb_env
103 mb_stdin mb_stdout mb_stderr
106 h <- runProcessWin32 "runProcess" cmd args mb_cwd mb_env
107 mb_stdin mb_stdout mb_stderr ""
109 maybe (return ()) hClose mb_stdin
110 maybe (return ()) hClose mb_stdout
111 maybe (return ()) hClose mb_stderr
114 -- ----------------------------------------------------------------------------
115 -- runInteractiveCommand
117 {- | Runs a command using the shell, and returns 'Handle's that may
118 be used to communicate with the process via its @stdin@, @stdout@,
119 and @stderr@ respectively.
121 runInteractiveCommand
123 -> IO (Handle,Handle,Handle,ProcessHandle)
125 runInteractiveCommand string = do
126 (cmd,args) <- commandToProcess string
127 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
128 runInteractiveProcess1 "runInteractiveCommand" cmd args Nothing Nothing
130 runInteractiveProcess1 "runInteractiveCommand" cmd [] Nothing Nothing args
133 -- ----------------------------------------------------------------------------
134 -- runInteractiveProcess
136 {- | Runs a raw command, and returns 'Handle's that may be used to communicate
137 with the process via its @stdin@, @stdout@ and @stderr@ respectively.
139 For example, to start a process and feed a string to its stdin:
141 > (inp,out,err,pid) <- runInteractiveProcess "..."
142 > forkIO (hPutStr inp str)
144 runInteractiveProcess
145 :: FilePath -- ^ Filename of the executable
146 -> [String] -- ^ Arguments to pass to the executable
147 -> Maybe FilePath -- ^ Optional path to the working directory
148 -> Maybe [(String,String)] -- ^ Optional environment (otherwise inherit)
149 -> IO (Handle,Handle,Handle,ProcessHandle)
151 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
153 runInteractiveProcess cmd args mb_cwd mb_env =
154 runInteractiveProcess1 "runInteractiveProcess" cmd args mb_cwd mb_env
156 runInteractiveProcess1 fun cmd args mb_cwd mb_env = do
157 withFilePathException cmd $
158 alloca $ \ pfdStdInput ->
159 alloca $ \ pfdStdOutput ->
160 alloca $ \ pfdStdError ->
161 maybeWith withCEnvironment mb_env $ \pEnv ->
162 maybeWith withCString mb_cwd $ \pWorkDir ->
163 withMany withCString (cmd:args) $ \cstrs ->
164 withArray0 nullPtr cstrs $ \pargs -> do
165 proc_handle <- throwErrnoIfMinus1 fun
166 (c_runInteractiveProcess pargs pWorkDir pEnv
167 pfdStdInput pfdStdOutput pfdStdError)
168 hndStdInput <- fdToHandle pfdStdInput WriteMode
169 hndStdOutput <- fdToHandle pfdStdOutput ReadMode
170 hndStdError <- fdToHandle pfdStdError ReadMode
171 ph <- mkProcessHandle proc_handle
172 return (hndStdInput, hndStdOutput, hndStdError, ph)
174 foreign import ccall unsafe "runInteractiveProcess"
175 c_runInteractiveProcess
186 runInteractiveProcess cmd args mb_cwd mb_env =
187 runInteractiveProcess1 "runInteractiveProcess" cmd args mb_cwd mb_env ""
189 runInteractiveProcess1 fun cmd args workDir env extra_cmdline
190 = withFilePathException cmd $ do
191 let cmdline = translate cmd ++
192 concat (map ((' ':) . translate) args) ++
193 (if null extra_cmdline then "" else ' ':extra_cmdline)
194 withCString cmdline $ \pcmdline ->
195 alloca $ \ pfdStdInput ->
196 alloca $ \ pfdStdOutput ->
197 alloca $ \ pfdStdError -> do
198 maybeWith withCEnvironment env $ \pEnv -> do
199 maybeWith withCString workDir $ \pWorkDir -> do
200 proc_handle <- throwErrnoIfMinus1 fun $
201 c_runInteractiveProcess pcmdline pWorkDir pEnv
202 pfdStdInput pfdStdOutput pfdStdError
203 hndStdInput <- fdToHandle pfdStdInput WriteMode
204 hndStdOutput <- fdToHandle pfdStdOutput ReadMode
205 hndStdError <- fdToHandle pfdStdError ReadMode
206 ph <- mkProcessHandle proc_handle
207 return (hndStdInput, hndStdOutput, hndStdError, ph)
209 foreign import ccall unsafe "runInteractiveProcess"
210 c_runInteractiveProcess
221 fdToHandle :: Ptr FD -> IOMode -> IO Handle
222 fdToHandle pfd mode = do
224 openFd fd (Just Stream)
225 False{-not a socket-}
226 ("fd:" ++ show fd) mode True{-binary-}
228 -- ----------------------------------------------------------------------------
231 {- | Waits for the specified process to terminate, and returns its exit code.
233 GHC Note: in order to call @waitForProcess@ without blocking all the
234 other threads in the system, you must compile the program with
240 waitForProcess ph = do
241 p_ <- withProcessHandle ph $ \p_ -> return (p_,p_)
243 ClosedHandle e -> return e
245 -- don't hold the MVar while we call c_waitForProcess...
246 -- (XXX but there's a small race window here during which another
247 -- thread could close the handle or call waitForProcess)
248 code <- throwErrnoIfMinus1 "waitForProcess" (c_waitForProcess h)
249 withProcessHandle ph $ \p_ ->
251 ClosedHandle e -> return (p_,e)
254 let e = if (code == 0)
256 else (ExitFailure (fromIntegral code))
257 return (ClosedHandle e, e)
259 -- ----------------------------------------------------------------------------
262 -- | Attempts to terminate the specified process. This function should
263 -- not be used under normal circumstances - no guarantees are given regarding
264 -- how cleanly the process is terminated. To check whether the process
265 -- has indeed terminated, use 'getProcessExitCode'.
267 -- On Unix systems, 'terminateProcess' sends the process the SIGKILL signal.
268 -- On Windows systems, the Win32 @TerminateProcess@ function is called, passing
269 -- an exit code of 1.
270 terminateProcess :: ProcessHandle -> IO ()
271 terminateProcess ph = do
272 withProcessHandle_ ph $ \p_ ->
274 ClosedHandle _ -> return p_
276 throwErrnoIfMinus1_ "terminateProcess" $ c_terminateProcess h
278 -- does not close the handle, we might want to try terminating it
279 -- again, or get its exit code.
281 -- ----------------------------------------------------------------------------
282 -- getProcessExitCode
285 This is a non-blocking version of 'waitForProcess'. If the process is
286 still running, 'Nothing' is returned. If the process has exited, then
287 @'Just' e@ is returned where @e@ is the exit code of the process.
288 Subsequent calls to @getProcessExitStatus@ always return @'Just'
289 'ExitSuccess'@, regardless of what the original exit code was.
291 getProcessExitCode :: ProcessHandle -> IO (Maybe ExitCode)
292 getProcessExitCode ph = do
293 withProcessHandle ph $ \p_ ->
295 ClosedHandle e -> return (p_, Just e)
297 alloca $ \pExitCode -> do
298 res <- throwErrnoIfMinus1 "getProcessExitCode" $
299 c_getProcessExitCode h pExitCode
300 code <- peek pExitCode
302 then return (p_, Nothing)
305 let e | code == 0 = ExitSuccess
306 | otherwise = ExitFailure (fromIntegral code)
307 return (ClosedHandle e, Just e)
309 -- ----------------------------------------------------------------------------
310 -- Interface to C bits
312 foreign import ccall unsafe "terminateProcess"
317 foreign import ccall unsafe "getProcessExitCode"
323 foreign import ccall safe "waitForProcess" -- NB. safe - can block