cabal-install-3.6.0.0: src/Distribution/Client/Compat/Process.hs
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.Client.Compat.Process
-- Copyright : (c) 2013 Liu Hao, Brent Yorgey
-- License : BSD-style (see the file LICENSE)
--
-- Maintainer : cabal-devel@haskell.org
-- Stability : provisional
-- Portability : portable
--
-- Cross-platform utilities for invoking processes.
--
-----------------------------------------------------------------------------
module Distribution.Client.Compat.Process (
readProcessWithExitCode
) where
import Prelude (FilePath, IO, String, return, (||))
import Control.Exception (catch, throw)
import System.Exit (ExitCode (ExitFailure))
import System.IO.Error (isDoesNotExistError, isPermissionError)
import qualified System.Process as P
-- | @readProcessWithExitCode@ creates an external process, reads its
-- standard output and standard error strictly, waits until the
-- process terminates, and then returns the @ExitCode@ of the
-- process, the standard output, and the standard error.
--
-- See the documentation of the version from @System.Process@ for
-- more information.
--
-- The version from @System.Process@ behaves inconsistently across
-- platforms when an executable with the given name is not found: in
-- some cases it returns an @ExitFailure@, in others it throws an
-- exception. This variant catches \"does not exist\" and
-- \"permission denied\" exceptions and turns them into
-- @ExitFailure@s.
--
-- TODO: this doesn't use 'Distrubution.Compat.Process'.
--
readProcessWithExitCode :: FilePath -> [String] -> String -> IO (ExitCode, String, String)
readProcessWithExitCode cmd args input =
P.readProcessWithExitCode cmd args input
`catch` \e -> if isDoesNotExistError e || isPermissionError e
then return (ExitFailure 127, "", "")
else throw e