module System.Unix.Process
( readProcess
, readProcessWithExitCode
) where
import Control.Concurrent (newEmptyMVar, forkIO, putMVar, takeMVar)
import qualified Control.Exception as C
import Control.Monad (when)
import qualified Data.ByteString.Lazy.Char8 as B
import GHC.IO.Exception (IOErrorType(OtherError))
import System.Exit (ExitCode(..))
import System.IO (hFlush, hClose)
import System.IO.Error (mkIOError)
import System.Process (CreateProcess(std_in, std_out, std_err, cwd), createProcess, waitForProcess, proc, StdStream(CreatePipe, Inherit), showCommandForUser)
readProcessWithExitCode
:: FilePath
-> [String]
-> (CreateProcess -> CreateProcess)
-> B.ByteString
-> IO (ExitCode, B.ByteString, B.ByteString)
readProcessWithExitCode cmd args modify input = do
let modify' p = modify (p {std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe })
(Just inh, Just outh, Just errh, pid) <-
createProcess (modify' (proc cmd args))
outMVar <- newEmptyMVar
out <- B.hGetContents outh
_ <- forkIO $ C.evaluate (B.length out) >> putMVar outMVar ()
err <- B.hGetContents errh
_ <- forkIO $ C.evaluate (B.length err) >> putMVar outMVar ()
when (not (B.null input)) $ do B.hPutStr inh input; hFlush inh
hClose inh
takeMVar outMVar
takeMVar outMVar
hClose outh
hClose errh
ex <- waitForProcess pid
return (ex, out, err)
readProcess
:: FilePath
-> [String]
-> (CreateProcess -> CreateProcess)
-> B.ByteString
-> IO B.ByteString
readProcess cmd args modify input = do
let modify' p = modify (p {std_in = CreatePipe, std_out = CreatePipe, std_err = Inherit })
(Just inh, Just outh, _, pid) <-
createProcess (modify' (proc cmd args))
output <- B.hGetContents outh
outMVar <- newEmptyMVar
_ <- forkIO $ C.evaluate (B.length output) >> putMVar outMVar ()
when (not (B.null input)) $ do B.hPutStr inh input; hFlush inh
hClose inh
takeMVar outMVar
hClose outh
ex <- waitForProcess pid
case ex of
ExitSuccess -> return output
ExitFailure r ->
ioError (mkIOError OtherError ("readProcess: " ++ showCommandForUser cmd args ++
" (exit " ++ show r ++ ")")
Nothing Nothing)