{-# LANGUAGE CPP,ScopedTypeVariables #-}
module Test.Framework.Process ( popen, popenShell ) where
import System.IO
import System.Process
import System.Exit
import Control.Concurrent (forkIO)
import qualified Control.Exception
popenShell :: String
-> Maybe String
-> IO (String,String,ExitCode)
popenShell :: String -> Maybe String -> IO (String, String, ExitCode)
popenShell String
cmd = IO (Handle, Handle, Handle, ProcessHandle)
-> Maybe String -> IO (String, String, ExitCode)
popen' (IO (Handle, Handle, Handle, ProcessHandle)
-> Maybe String -> IO (String, String, ExitCode))
-> IO (Handle, Handle, Handle, ProcessHandle)
-> Maybe String
-> IO (String, String, ExitCode)
forall a b. (a -> b) -> a -> b
$ String -> IO (Handle, Handle, Handle, ProcessHandle)
runInteractiveCommand String
cmd
popen :: FilePath
-> [String]
-> Maybe String
-> IO (String,String,ExitCode)
popen :: String -> [String] -> Maybe String -> IO (String, String, ExitCode)
popen String
file [String]
args =
IO (Handle, Handle, Handle, ProcessHandle)
-> Maybe String -> IO (String, String, ExitCode)
popen' (IO (Handle, Handle, Handle, ProcessHandle)
-> Maybe String -> IO (String, String, ExitCode))
-> IO (Handle, Handle, Handle, ProcessHandle)
-> Maybe String
-> IO (String, String, ExitCode)
forall a b. (a -> b) -> a -> b
$ String
-> [String]
-> Maybe String
-> Maybe [(String, String)]
-> IO (Handle, Handle, Handle, ProcessHandle)
runInteractiveProcess String
file [String]
args Maybe String
forall a. Maybe a
Nothing Maybe [(String, String)]
forall a. Maybe a
Nothing
popen' :: IO (Handle, Handle, Handle, ProcessHandle)
-> Maybe String
-> IO (String,String,ExitCode)
popen' :: IO (Handle, Handle, Handle, ProcessHandle)
-> Maybe String -> IO (String, String, ExitCode)
popen' IO (Handle, Handle, Handle, ProcessHandle)
run Maybe String
minput =
(SomeException -> IO (String, String, ExitCode))
-> IO (String, String, ExitCode) -> IO (String, String, ExitCode)
forall e a. Exception e => (e -> IO a) -> IO a -> IO a
Control.Exception.handle (\ (SomeException
e :: Control.Exception.SomeException) ->
(String, String, ExitCode) -> IO (String, String, ExitCode)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([],SomeException -> String
forall a. Show a => a -> String
show SomeException
e,String -> ExitCode
forall a. HasCallStack => String -> a
error (SomeException -> String
forall a. Show a => a -> String
show SomeException
e))) (IO (String, String, ExitCode) -> IO (String, String, ExitCode))
-> IO (String, String, ExitCode) -> IO (String, String, ExitCode)
forall a b. (a -> b) -> a -> b
$ do
(Handle
inp,Handle
out,Handle
err,ProcessHandle
pid) <- IO (Handle, Handle, Handle, ProcessHandle)
run
case Maybe String
minput of
Just String
input -> Handle -> String -> IO ()
hPutStr Handle
inp String
input IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Handle -> IO ()
hClose Handle
inp
Maybe String
Nothing -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
String
output <- Handle -> IO String
hGetContents Handle
out
String
errput <- Handle -> IO String
hGetContents Handle
err
ThreadId
_ <- IO () -> IO ThreadId
forkIO (Int -> IO Int
forall a. a -> IO a
Control.Exception.evaluate (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
output) IO Int -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ())
ThreadId
_ <- IO () -> IO ThreadId
forkIO (Int -> IO Int
forall a. a -> IO a
Control.Exception.evaluate (String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
errput) IO Int -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ())
ExitCode
ecode <- ProcessHandle -> IO ExitCode
waitForProcess ProcessHandle
pid
(String, String, ExitCode) -> IO (String, String, ExitCode)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String
output,String
errput,ExitCode
ecode)