process-extras-0.2.0: src/System/Process/Text/Lazy.hs
module System.Process.Text.Lazy where
import Control.DeepSeq (rnf)
import Control.Exception
import qualified Control.Exception as C (evaluate)
import Control.Monad
import Data.Text.Lazy (Text)
import qualified Data.Text.Lazy as T
import qualified Data.Text.Lazy.IO as T
import System.Process
import System.Exit (ExitCode)
import System.IO
import Utils (forkWait)
-- | Like 'System.Process.readProcessWithExitCode', but using 'Text'
readProcessWithExitCode
:: FilePath -- ^ command to run
-> [String] -- ^ any arguments
-> Text -- ^ standard input
-> IO (ExitCode, Text, Text) -- ^ exitcode, stdout, stderr
readProcessWithExitCode cmd args input = mask $ \restore -> do
(Just inh, Just outh, Just errh, pid) <-
createProcess (proc cmd args){ std_in = CreatePipe,
std_out = CreatePipe,
std_err = CreatePipe }
flip onException
(do hClose inh; hClose outh; hClose errh;
terminateProcess pid; waitForProcess pid) $ restore $ do
-- fork off a thread to start consuming stdout
out <- T.hGetContents outh
waitOut <- forkWait $ C.evaluate $ rnf out
-- fork off a thread to start consuming stderr
err <- T.hGetContents errh
waitErr <- forkWait $ C.evaluate $ rnf err
-- now write and flush any input
unless (T.null input) $ do T.hPutStr inh input; hFlush inh
hClose inh -- done with stdin
-- wait on the output
waitOut
waitErr
hClose outh
hClose errh
-- wait on the process
ex <- waitForProcess pid
return (ex, out, err)