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 )
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
86 Any 'Handle's passed to 'runProcess' are placed immediately in the
87 closed state, so may no longer be referenced by the Haskell process.
90 :: FilePath -- ^ Filename of the executable
91 -> [String] -- ^ Arguments to pass to the executable
92 -> Maybe FilePath -- ^ Optional path to the working directory
93 -> Maybe [(String,String)] -- ^ Optional environment (otherwise inherit)
94 -> Maybe Handle -- ^ Handle to use for @stdin@
95 -> Maybe Handle -- ^ Handle to use for @stdout@
96 -> Maybe Handle -- ^ Handle to use for @stderr@
99 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
101 runProcess cmd args mb_cwd mb_env mb_stdin mb_stdout mb_stderr
102 = runProcessPosix "runProcess" cmd args mb_cwd mb_env
103 mb_stdin mb_stdout mb_stderr
108 runProcess cmd args mb_cwd mb_env mb_stdin mb_stdout mb_stderr =
109 runProcess1 "runProcess" cmd args mb_cwd mb_env
110 mb_stdin mb_stdout mb_stderr ""
112 runProcessWin32 fun cmd args mb_cwd mb_env
113 mb_stdin mb_stdout mb_stderr extra_cmdline
114 = withFilePathException cmd $
115 withHandle_ fun (fromMaybe stdin mb_stdin) $ \hndStdInput ->
116 withHandle_ fun (fromMaybe stdout mb_stdout) $ \hndStdOutput ->
117 withHandle_ fun (fromMaybe stderr mb_stderr) $ \hndStdError ->
118 maybeWith withCEnvironment mb_env $ \pEnv -> do
119 maybeWith withCString mb_cwd $ \pWorkDir -> do
120 let cmdline = translate cmd ++
121 concat (map ((' ':) . translate) args) ++
122 (if null extra_cmdline then "" else ' ':extra_cmdline)
123 withCString cmdline $ \pcmdline -> do
124 proc_handle <- throwErrnoIfMinus1 fun
125 (c_runProcess pcmdline pWorkDir pEnv
129 return (ProcessHandle proc_handle)
131 foreign import ccall unsafe "runProcess"
141 -- Set the standard HANDLEs for the child process appropriately. NOTE:
142 -- this relies on the HANDLEs being inheritable. By default, the
143 -- runtime open() function creates inheritable handles (unless O_NOINHERIT
144 -- is specified). But perhaps we should DuplicateHandle() to make sure
145 -- the handle is inheritable?
148 -- ----------------------------------------------------------------------------
149 -- runInteractiveCommand
151 {- | Runs a command using the shell, and returns 'Handle's that may
152 be used to communicate with the process via its @stdin@, @stdout@,
153 and @stderr@ respectively.
155 runInteractiveCommand
157 -> IO (Handle,Handle,Handle,ProcessHandle)
159 runInteractiveCommand string = do
160 (cmd,args) <- commandToProcess string
161 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
162 runInteractiveProcess1 "runInteractiveCommand" cmd args Nothing Nothing
164 runInteractiveProcess1 "runInteractiveCommand" cmd [] Nothing Nothing args
167 -- ----------------------------------------------------------------------------
168 -- runInteractiveProcess
170 {- | Runs a raw command, and returns 'Handle's that may be used to communicate
171 with the process via its @stdin@, @stdout@ and @stderr@ respectively.
173 For example, to start a process and feed a string to its stdin:
175 > (in,out,err,pid) <- runInteractiveProcess "..."
176 > forkIO (hPutStr in str)
178 runInteractiveProcess
179 :: FilePath -- ^ Filename of the executable
180 -> [String] -- ^ Arguments to pass to the executable
181 -> Maybe FilePath -- ^ Optional path to the working directory
182 -> Maybe [(String,String)] -- ^ Optional environment (otherwise inherit)
183 -> IO (Handle,Handle,Handle,ProcessHandle)
185 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
187 runInteractiveProcess cmd args mb_cwd mb_env =
188 runInteractiveProcess1 "runInteractiveProcess" cmd args mb_cwd mb_env
190 runInteractiveProcess1 fun cmd args mb_cwd mb_env = do
191 withFilePathException cmd $
192 alloca $ \ pfdStdInput ->
193 alloca $ \ pfdStdOutput ->
194 alloca $ \ pfdStdError ->
195 maybeWith withCEnvironment mb_env $ \pEnv ->
196 maybeWith withCString mb_cwd $ \pWorkDir ->
197 withMany withCString (cmd:args) $ \cstrs ->
198 withArray0 nullPtr cstrs $ \pargs -> do
199 proc_handle <- throwErrnoIfMinus1 fun
200 (c_runInteractiveProcess pargs pWorkDir pEnv
201 pfdStdInput pfdStdOutput pfdStdError)
202 hndStdInput <- fdToHandle pfdStdInput WriteMode
203 hndStdOutput <- fdToHandle pfdStdOutput ReadMode
204 hndStdError <- fdToHandle pfdStdError ReadMode
205 return (hndStdInput, hndStdOutput, hndStdError, ProcessHandle proc_handle)
207 foreign import ccall unsafe "runInteractiveProcess"
208 c_runInteractiveProcess
219 runInteractiveProcess cmd args mb_cwd mb_env =
220 runInteractiveProcess1 "runInteractiveProcess" cmd args mb_cwd mb_env ""
222 runInteractiveProcess1 fun cmd args workDir env extra_cmdline
223 = withFilePathException cmd $ do
224 let cmdline = translate cmd ++
225 concat (map ((' ':) . translate) args) ++
226 (if null extra_cmdline then "" else ' ':extra_cmdline)
227 withCString cmdline $ \pcmdline ->
228 alloca $ \ pfdStdInput ->
229 alloca $ \ pfdStdOutput ->
230 alloca $ \ pfdStdError -> do
231 maybeWith withCEnvironment env $ \pEnv -> do
232 maybeWith withCString workDir $ \pWorkDir -> do
233 proc_handle <- throwErrnoIfMinus1 fun $
234 c_runInteractiveProcess pcmdline pWorkDir pEnv
235 pfdStdInput pfdStdOutput pfdStdError
236 hndStdInput <- fdToHandle pfdStdInput WriteMode
237 hndStdOutput <- fdToHandle pfdStdOutput ReadMode
238 hndStdError <- fdToHandle pfdStdError ReadMode
239 return (hndStdInput, hndStdOutput, hndStdError,
240 ProcessHandle proc_handle)
242 foreign import ccall unsafe "runInteractiveProcess"
243 c_runInteractiveProcess
254 fdToHandle :: Ptr FD -> IOMode -> IO Handle
255 fdToHandle pfd mode = do
257 openFd fd (Just Stream)
258 False{-not a socket-}
259 ("fd:" ++ show fd) mode True{-binary-}
261 -- ----------------------------------------------------------------------------
264 {- | Waits for the specified process to terminate, and returns its exit code.
266 GHC Note: in order to call waitForProcess without blocking all the
267 other threads in the system, you must compile the program with
273 waitForProcess (ProcessHandle handle) = do
274 code <- throwErrnoIfMinus1 "waitForProcess" (c_waitForProcess handle)
276 then return ExitSuccess
277 else return (ExitFailure (fromIntegral code))
279 -- ----------------------------------------------------------------------------
282 -- | Attempts to terminate the specified process. This function should
283 -- not be used under normal circumstances - no guarantees are given regarding
284 -- how cleanly the process is terminated. To check whether the process
285 -- has indeed terminated, use 'getProcessExitCode'.
287 -- On Unix systems, 'terminateProcess' sends the process the SIGKILL signal.
288 -- On Windows systems, the Win32 @TerminateProcess@ function is called, passing
289 -- an exit code of 1.
290 terminateProcess :: ProcessHandle -> IO ()
291 terminateProcess (ProcessHandle pid) =
292 throwErrnoIfMinus1_ "terminateProcess" (c_terminateProcess pid)
294 -- ----------------------------------------------------------------------------
295 -- getProcessExitCode
297 {- | Verifies whether the process is completed and if it is then returns the exit code.
298 If the process is still running the function returns Nothing
300 getProcessExitCode :: ProcessHandle -> IO (Maybe ExitCode)
301 getProcessExitCode (ProcessHandle handle) =
302 alloca $ \pExitCode -> do
303 res <- throwErrnoIfMinus1 "getProcessExitCode" (c_getProcessExitCode handle pExitCode)
304 code <- peek pExitCode
308 then return (Just ExitSuccess)
309 else return (Just (ExitFailure (fromIntegral code)))
311 -- ----------------------------------------------------------------------------
312 -- Interface to C bits
314 foreign import ccall unsafe "terminateProcess"
319 foreign import ccall unsafe "getProcessExitCode"
325 foreign import ccall safe "waitForProcess" -- NB. safe - can block
330 -- ------------------------------------------------------------------------
331 -- Passing commands to the OS on Windows
334 On Windows this is tricky. We use CreateProcess, passing a single
335 command-line string (lpCommandLine) as its argument. (CreateProcess
336 is well documented on http://msdn.microsoft/com.)
338 - It parses the beginning of the string to find the command. If the
339 file name has embedded spaces, it must be quoted, using double
341 "foo\this that\cmd" arg1 arg2
343 - The invoked command can in turn access the entire lpCommandLine string,
344 and the C runtime does indeed do so, parsing it to generate the
345 traditional argument vector argv[0], argv[1], etc. It does this
346 using a complex and arcane set of rules which are described here:
348 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/progs_12.asp
350 (if this URL stops working, you might be able to find it by
351 searching for "Parsing C Command-Line Arguments" on MSDN. Also,
352 the code in the Microsoft C runtime that does this translation
353 is shipped with VC++).
355 Our goal in runProcess is to take a command filename and list of
356 arguments, and construct a string which inverts the translatsions
357 described above, such that the program at the other end sees exactly
358 the same arguments in its argv[] that we passed to rawSystem.
360 This inverse translation is implemented by 'translate' below.
362 Here are some pages that give informations on Windows-related
363 limitations and deviations from Unix conventions:
365 http://support.microsoft.com/default.aspx?scid=kb;en-us;830473
366 Command lines and environment variables effectively limited to 8191
367 characters on Win XP, 2047 on NT/2000 (probably even less on Win 9x):
369 http://www.microsoft.com/windowsxp/home/using/productdoc/en/default.asp?url=/WINDOWSXP/home/using/productdoc/en/percent.asp
370 Command-line substitution under Windows XP. IIRC these facilities (or at
371 least a large subset of them) are available on Win NT and 2000. Some
372 might be available on Win 9x.
374 http://www.microsoft.com/windowsxp/home/using/productdoc/en/default.asp?url=/WINDOWSXP/home/using/productdoc/en/Cmd.asp
375 How CMD.EXE processes command lines.
378 Note: CreateProcess does have a separate argument (lpApplicationName)
379 with which you can specify the command, but we have to slap the
380 command into lpCommandLine anyway, so that argv[0] is what a C program
381 expects (namely the application name). So it seems simpler to just
382 use lpCommandLine alone, which CreateProcess supports.
385 #if defined(mingw32_HOST_OS)
387 -- Translate command-line arguments for passing to CreateProcess().
388 translate :: String -> String
389 translate str = '"' : snd (foldr escape (True,"\"") str)
390 where escape '"' (b, str) = (True, '\\' : '"' : str)
391 escape '\\' (True, str) = (True, '\\' : '\\' : str)
392 escape '\\' (False, str) = (False, '\\' : str)
393 escape c (b, str) = (False, c : str)
394 -- See long comment above for what this function is trying to do.
396 -- The Bool passed back along the string is True iff the
397 -- rest of the string is a sequence of backslashes followed by