never executed always true always false
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module : Distribution.Client.Compat.Process
4 -- Copyright : (c) 2013 Liu Hao, Brent Yorgey
5 -- License : BSD-style (see the file LICENSE)
6 --
7 -- Maintainer : cabal-devel@haskell.org
8 -- Stability : provisional
9 -- Portability : portable
10 --
11 -- Cross-platform utilities for invoking processes.
12 --
13 -----------------------------------------------------------------------------
14
15 module Distribution.Client.Compat.Process (
16 readProcessWithExitCode
17 ) where
18
19 import Prelude (FilePath, IO, String, return, (||))
20
21 import Control.Exception (catch, throw)
22 import System.Exit (ExitCode (ExitFailure))
23 import System.IO.Error (isDoesNotExistError, isPermissionError)
24 import qualified System.Process as P
25
26 -- | @readProcessWithExitCode@ creates an external process, reads its
27 -- standard output and standard error strictly, waits until the
28 -- process terminates, and then returns the @ExitCode@ of the
29 -- process, the standard output, and the standard error.
30 --
31 -- See the documentation of the version from @System.Process@ for
32 -- more information.
33 --
34 -- The version from @System.Process@ behaves inconsistently across
35 -- platforms when an executable with the given name is not found: in
36 -- some cases it returns an @ExitFailure@, in others it throws an
37 -- exception. This variant catches \"does not exist\" and
38 -- \"permission denied\" exceptions and turns them into
39 -- @ExitFailure@s.
40 --
41 -- TODO: this doesn't use 'Distrubution.Compat.Process'.
42 --
43 readProcessWithExitCode :: FilePath -> [String] -> String -> IO (ExitCode, String, String)
44 readProcessWithExitCode cmd args input =
45 P.readProcessWithExitCode cmd args input
46 `catch` \e -> if isDoesNotExistError e || isPermissionError e
47 then return (ExitFailure 127, "", "")
48 else throw e