module System.Process.ListLike where
import Control.Exception
import Control.Monad
import Data.ListLike (null)
import Data.ListLike.IO (ListLikeIO, hGetContents, hPutStr)
import Prelude hiding (null)
import System.Exit (ExitCode)
import System.IO (hClose, hFlush)
import System.Process
import Utils (forkWait)
class ListLikeIO a c => ListLikeProcessIO a c where
forceOutput :: a -> IO a
readProcessWithExitCode
:: ListLikeProcessIO a c =>
FilePath
-> [String]
-> a
-> IO (ExitCode, a, a)
readProcessWithExitCode cmd args input = readCreateProcessWithExitCode (proc cmd args) input
readCreateProcessWithExitCode :: ListLikeProcessIO a c => CreateProcess -> a -> IO (ExitCode, a, a)
readCreateProcessWithExitCode p input = mask $ \restore -> do
(Just inh, Just outh, Just errh, pid) <-
createProcess p{ std_in = CreatePipe,
std_out = CreatePipe,
std_err = CreatePipe }
flip onException
(do terminateProcess pid; hClose inh; hClose outh; hClose errh;
waitForProcess pid) $ restore $ do
waitOut <- forkWait $ hGetContents outh >>= forceOutput
waitErr <- forkWait $ hGetContents errh >>= forceOutput
unless (null input) $ do hPutStr inh input; hFlush inh
hClose inh
out <- waitOut
err <- waitErr
hClose outh
hClose errh
ex <- waitForProcess pid
return (ex, out, err)