module System.IO.Streams.Process
( module System.Process
, runInteractiveCommand
, runInteractiveProcess
) where
import Data.ByteString.Char8 (ByteString)
import System.IO (hClose)
import System.Process (CmdSpec (..), CreateProcess (CreateProcess, close_fds, cmdspec, create_group, cwd, std_err, std_in, std_out), ProcessHandle, StdStream (..), createProcess, getProcessExitCode, interruptProcessGroupOf, proc, rawSystem, readProcess, readProcessWithExitCode, runCommand, shell, showCommandForUser, system, terminateProcess, waitForProcess)
import qualified System.IO.Streams.Combinators as Streams
import qualified System.IO.Streams.Handle as Streams
import System.IO.Streams.Internal (InputStream, OutputStream)
import qualified System.IO.Streams.Internal as Streams
import qualified System.Process as P
runInteractiveCommand :: String
-> IO (OutputStream ByteString,
InputStream ByteString,
InputStream ByteString,
ProcessHandle)
runInteractiveCommand :: String
-> IO
(OutputStream ByteString, InputStream ByteString,
InputStream ByteString, ProcessHandle)
runInteractiveCommand String
scmd = do
(Handle
hin, Handle
hout, Handle
herr, ProcessHandle
ph) <- String -> IO (Handle, Handle, Handle, ProcessHandle)
P.runInteractiveCommand String
scmd
OutputStream ByteString
sIn <- Handle -> IO (OutputStream ByteString)
Streams.handleToOutputStream Handle
hin IO (OutputStream ByteString)
-> (OutputStream ByteString -> IO (OutputStream ByteString))
-> IO (OutputStream ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
IO () -> OutputStream ByteString -> IO (OutputStream ByteString)
forall b a. IO b -> OutputStream a -> IO (OutputStream a)
Streams.atEndOfOutput (Handle -> IO ()
hClose Handle
hin) IO (OutputStream ByteString)
-> (OutputStream ByteString -> IO (OutputStream ByteString))
-> IO (OutputStream ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
OutputStream ByteString -> IO (OutputStream ByteString)
forall a. OutputStream a -> IO (OutputStream a)
Streams.lockingOutputStream
InputStream ByteString
sOut <- Handle -> IO (InputStream ByteString)
Streams.handleToInputStream Handle
hout IO (InputStream ByteString)
-> (InputStream ByteString -> IO (InputStream ByteString))
-> IO (InputStream ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
IO () -> InputStream ByteString -> IO (InputStream ByteString)
forall b a. IO b -> InputStream a -> IO (InputStream a)
Streams.atEndOfInput (Handle -> IO ()
hClose Handle
hout) IO (InputStream ByteString)
-> (InputStream ByteString -> IO (InputStream ByteString))
-> IO (InputStream ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
InputStream ByteString -> IO (InputStream ByteString)
forall a. InputStream a -> IO (InputStream a)
Streams.lockingInputStream
InputStream ByteString
sErr <- Handle -> IO (InputStream ByteString)
Streams.handleToInputStream Handle
herr IO (InputStream ByteString)
-> (InputStream ByteString -> IO (InputStream ByteString))
-> IO (InputStream ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
IO () -> InputStream ByteString -> IO (InputStream ByteString)
forall b a. IO b -> InputStream a -> IO (InputStream a)
Streams.atEndOfInput (Handle -> IO ()
hClose Handle
herr) IO (InputStream ByteString)
-> (InputStream ByteString -> IO (InputStream ByteString))
-> IO (InputStream ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
InputStream ByteString -> IO (InputStream ByteString)
forall a. InputStream a -> IO (InputStream a)
Streams.lockingInputStream
(OutputStream ByteString, InputStream ByteString,
InputStream ByteString, ProcessHandle)
-> IO
(OutputStream ByteString, InputStream ByteString,
InputStream ByteString, ProcessHandle)
forall (m :: * -> *) a. Monad m => a -> m a
return (OutputStream ByteString
sIn, InputStream ByteString
sOut, InputStream ByteString
sErr, ProcessHandle
ph)
runInteractiveProcess
:: FilePath
-> [String]
-> Maybe FilePath
-> Maybe [(String,String)]
-> IO (OutputStream ByteString,
InputStream ByteString,
InputStream ByteString,
ProcessHandle)
runInteractiveProcess :: String
-> [String]
-> Maybe String
-> Maybe [(String, String)]
-> IO
(OutputStream ByteString, InputStream ByteString,
InputStream ByteString, ProcessHandle)
runInteractiveProcess String
cmd [String]
args Maybe String
wd Maybe [(String, String)]
env = do
(Handle
hin, Handle
hout, Handle
herr, ProcessHandle
ph) <- String
-> [String]
-> Maybe String
-> Maybe [(String, String)]
-> IO (Handle, Handle, Handle, ProcessHandle)
P.runInteractiveProcess String
cmd [String]
args Maybe String
wd Maybe [(String, String)]
env
OutputStream ByteString
sIn <- Handle -> IO (OutputStream ByteString)
Streams.handleToOutputStream Handle
hin IO (OutputStream ByteString)
-> (OutputStream ByteString -> IO (OutputStream ByteString))
-> IO (OutputStream ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
IO () -> OutputStream ByteString -> IO (OutputStream ByteString)
forall b a. IO b -> OutputStream a -> IO (OutputStream a)
Streams.atEndOfOutput (Handle -> IO ()
hClose Handle
hin) IO (OutputStream ByteString)
-> (OutputStream ByteString -> IO (OutputStream ByteString))
-> IO (OutputStream ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
OutputStream ByteString -> IO (OutputStream ByteString)
forall a. OutputStream a -> IO (OutputStream a)
Streams.lockingOutputStream
InputStream ByteString
sOut <- Handle -> IO (InputStream ByteString)
Streams.handleToInputStream Handle
hout IO (InputStream ByteString)
-> (InputStream ByteString -> IO (InputStream ByteString))
-> IO (InputStream ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
IO () -> InputStream ByteString -> IO (InputStream ByteString)
forall b a. IO b -> InputStream a -> IO (InputStream a)
Streams.atEndOfInput (Handle -> IO ()
hClose Handle
hout) IO (InputStream ByteString)
-> (InputStream ByteString -> IO (InputStream ByteString))
-> IO (InputStream ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
InputStream ByteString -> IO (InputStream ByteString)
forall a. InputStream a -> IO (InputStream a)
Streams.lockingInputStream
InputStream ByteString
sErr <- Handle -> IO (InputStream ByteString)
Streams.handleToInputStream Handle
herr IO (InputStream ByteString)
-> (InputStream ByteString -> IO (InputStream ByteString))
-> IO (InputStream ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
IO () -> InputStream ByteString -> IO (InputStream ByteString)
forall b a. IO b -> InputStream a -> IO (InputStream a)
Streams.atEndOfInput (Handle -> IO ()
hClose Handle
herr) IO (InputStream ByteString)
-> (InputStream ByteString -> IO (InputStream ByteString))
-> IO (InputStream ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
InputStream ByteString -> IO (InputStream ByteString)
forall a. InputStream a -> IO (InputStream a)
Streams.lockingInputStream
(OutputStream ByteString, InputStream ByteString,
InputStream ByteString, ProcessHandle)
-> IO
(OutputStream ByteString, InputStream ByteString,
InputStream ByteString, ProcessHandle)
forall (m :: * -> *) a. Monad m => a -> m a
return (OutputStream ByteString
sIn, InputStream ByteString
sOut, InputStream ByteString
sErr, ProcessHandle
ph)