{-# LANGUAGE CPP #-}
module System.Plugins.Process (exec, popen) where
import System.Exit
import System.IO
import System.Process
import Control.Concurrent (forkIO)
import qualified Control.Exception as E
exec :: String -> [String] -> IO ([String],[String],Bool)
exec f as = do
(a,b,c,_) <- popen f as (Just [])
return (lines a, lines b,c)
type ProcessID = ProcessHandle
popen :: FilePath -> [String] -> Maybe String -> IO (String,String,Bool,ProcessID)
popen file args minput =
E.handle (\e -> return ([],show (e::E.IOException), False, error (show e))) $ do
(inp,out,err,pid) <- runInteractiveProcess file args Nothing Nothing
case minput of
Just input -> hPutStr inp input >> hClose inp
Nothing -> return ()
output <- hGetContents out
errput <- hGetContents err
_ <- forkIO (E.evaluate (length output) >> return ())
_ <- forkIO (E.evaluate (length errput) >> return ())
exitCode <- waitForProcess pid
case exitCode of
ExitFailure code
| null errput -> let errMsg = file ++ ": failed with error code " ++ show code
in return ([],errMsg,False,error errMsg)
| otherwise -> return ([],errput,False,error errput)
_ -> return (output,errput,True,pid)