{-|
    Author      :  Sergei Trofimovich <slyfox@inbox.ru>
    Stability   :  experimental
    Portability :  haskell98

    Ungrouped utilitary stuff lays here until someone finds better place for it :]
-}

module Util
    ( run_cmd -- :: String -> IO (Maybe String)
    ) where

import System.IO
import System.Process
import System.Exit (ExitCode(..))

-- 'run_cmd' executes command and returns it's standard output
-- as 'String'.

run_cmd :: String -> IO (Maybe String)
run_cmd :: String -> IO (Maybe String)
run_cmd String
cmd = do (Handle
hI, Handle
hO, Handle
hE, ProcessHandle
hProcess) <- String -> IO (Handle, Handle, Handle, ProcessHandle)
runInteractiveCommand String
cmd
                 Handle -> IO ()
hClose Handle
hI
                 String
output <- Handle -> IO String
hGetContents Handle
hO
                 String
errors <- Handle -> IO String
hGetContents Handle
hE -- TODO: propagate error to caller
                 String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
output Int -> IO () -> IO ()
`seq` Handle -> IO ()
hClose Handle
hO
                 String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
errors Int -> IO () -> IO ()
`seq` Handle -> IO ()
hClose Handle
hE

                 ExitCode
exitCode <- ProcessHandle -> IO ExitCode
waitForProcess ProcessHandle
hProcess
                 Maybe String -> IO (Maybe String)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe String -> IO (Maybe String))
-> Maybe String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ if (String
output String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"" Bool -> Bool -> Bool
|| ExitCode
exitCode ExitCode -> ExitCode -> Bool
forall a. Eq a => a -> a -> Bool
/= ExitCode
ExitSuccess)
                          then Maybe String
forall a. Maybe a
Nothing
                          else String -> Maybe String
forall a. a -> Maybe a
Just String
output