module RawFilePath.Process.Utility
( callProcess
, readProcessWithExitCode
) where
import RawFilePath.Import
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as LB
import qualified Data.ByteString.Builder as B
import RawFilePath.Process.Common
import RawFilePath.Process.Basic
callProcess :: ProcessConf stdin stdout stderr -> IO ExitCode
callProcess :: forall stdin stdout stderr.
ProcessConf stdin stdout stderr -> IO ExitCode
callProcess ProcessConf stdin stdout stderr
conf = IO (Process NoStream NoStream NoStream)
start forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall stdin stdout stderr.
Process stdin stdout stderr -> IO ExitCode
waitForProcess
where
start :: IO (Process NoStream NoStream NoStream)
start = forall stdin stdout stderr.
(StreamType stdin, StreamType stdout, StreamType stderr) =>
ProcessConf stdin stdout stderr -> IO (Process stdin stdout stderr)
startProcess ProcessConf stdin stdout stderr
conf
{ cfgStdin :: NoStream
cfgStdin = NoStream
NoStream
, cfgStdout :: NoStream
cfgStdout = NoStream
NoStream
, cfgStderr :: NoStream
cfgStderr = NoStream
NoStream
}
readProcessWithExitCode
:: ProcessConf stdin stdout stderr
-> IO (ExitCode, ByteString, ByteString)
readProcessWithExitCode :: forall stdin stdout stderr.
ProcessConf stdin stdout stderr
-> IO (ExitCode, ByteString, ByteString)
readProcessWithExitCode ProcessConf stdin stdout stderr
conf = do
Process NoStream CreatePipe CreatePipe
process <- forall stdin stdout stderr.
(StreamType stdin, StreamType stdout, StreamType stderr) =>
ProcessConf stdin stdout stderr -> IO (Process stdin stdout stderr)
startProcess ProcessConf stdin stdout stderr
conf
{ cfgStdin :: NoStream
cfgStdin = NoStream
NoStream
, cfgStdout :: CreatePipe
cfgStdout = CreatePipe
CreatePipe
, cfgStderr :: CreatePipe
cfgStderr = CreatePipe
CreatePipe
}
ByteString
stdoutB <- Handle -> IO ByteString
hGetAll (forall stdin stderr. Process stdin CreatePipe stderr -> Handle
processStdout Process NoStream CreatePipe CreatePipe
process)
ByteString
stderrB <- Handle -> IO ByteString
hGetAll (forall stdin stdout. Process stdin stdout CreatePipe -> Handle
processStderr Process NoStream CreatePipe CreatePipe
process)
ExitCode
exitCode <- forall stdin stdout stderr.
Process stdin stdout stderr -> IO ExitCode
waitForProcess Process NoStream CreatePipe CreatePipe
process
forall (m :: * -> *) a. Monad m => a -> m a
return (ExitCode
exitCode, ByteString
stdoutB, ByteString
stderrB)
hGetAll :: Handle -> IO ByteString
hGetAll :: Handle -> IO ByteString
hGetAll Handle
h = ByteString -> ByteString
LB.toStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> ByteString
B.toLazyByteString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {t}. Builder -> t -> IO Builder
hGetAll' forall a. Monoid a => a
mempty Handle
h
where
hGetAll' :: Builder -> t -> IO Builder
hGetAll' Builder
acc t
h' = forall a. IO a -> IO (Either IOError a)
tryIOError (Handle -> IO ByteString
B.hGetContents Handle
h) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ case
Left IOError
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return Builder
acc
Right ByteString
b -> Builder -> t -> IO Builder
hGetAll' (Builder
acc forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
B.byteString ByteString
b) t
h'