Pipe 2.0.1 → 2.1.0
raw patch · 2 files changed
+29/−9 lines, 2 filesdep +unixPVP ok
version bump matches the API change (PVP)
Dependencies added: unix
API changes (from Hackage documentation)
Files
- Pipe.cabal +4/−1
- System/Process/Pipe.hs +25/−8
Pipe.cabal view
@@ -1,7 +1,7 @@ Cabal-Version: >= 1.2 Name: Pipe -Version: 2.0.1 +Version: 2.1.0 Homepage: http://iki.fi/matti.niemenmaa/pipe/ Synopsis: Process piping library Category: System @@ -20,3 +20,6 @@ process >= 1.0.1 && < 2, filepath >= 1.1 && < 2 Exposed-Modules: System.Process.Pipe + + if !os(windows) + Build-Depends: unix >= 2.3 && < 3
System/Process/Pipe.hs view
@@ -33,16 +33,21 @@ ) where import Control.Concurrent (forkIO) +import Control.Exception (try, IOException) import Control.Monad (mplus) -import Data.Maybe (fromJust) import System.FilePath (dropFileName) import System.IO ( withBinaryFile, IOMode (ReadMode, WriteMode) - , Handle, hGetContents, hPutStr) + , Handle, hGetContents, hPutStr, hClose) import System.Process ( CreateProcess(..), createProcess , CmdSpec (RawCommand) , StdStream (CreatePipe, Inherit, UseHandle) , ProcessHandle, waitForProcess) +#if !mingw32_HOST_OS +import Control.Exception (bracket) +import System.Posix.Signals (installHandler, sigPIPE, Handler(Ignore)) +#endif + createProc :: FilePath -> StdStream -> StdStream -> (FilePath,[String]) -> IO (Maybe Handle, Maybe Handle, ProcessHandle) createProc wdir inp out (p,args) = do @@ -74,8 +79,8 @@ return (firstI `mplus` i', o, reverse (pid:pids)) f pids firstI i (p:ps) = do - (i',o,pid) <- createProc wdir i CreatePipe p - f (pid:pids) (firstI `mplus` i') (UseHandle . fromJust $ o) ps + (i',Just o,pid) <- createProc wdir i CreatePipe p + f (pid:pids) (firstI `mplus` i') (UseHandle o) ps -- | Pipes the input, using the given writer and reader functions, through all -- the commands named, in the given working directory. Returns the result. @@ -84,15 +89,27 @@ -- -- The writer function is called in a 'forkIO'\'d thread, allowing this to be -- lazy. +-- +-- SIGPIPE is ignored in the writer thread. Likewise, any IOExceptions are +-- caught and ignored. pipe :: (Handle -> a -> IO ()) -> (Handle -> IO b) -> FilePath -> [(FilePath,[String])] -> a -> IO b -pipe writer reader wdir progs i = do - (inp, out, pids) <- pipeline wdir CreatePipe CreatePipe progs +pipe writer reader wdir progs dat = do + (Just inp, Just out, pids) <- pipeline wdir CreatePipe CreatePipe progs - forkIO (writer (fromJust inp) i >> mapM_ waitForProcess pids) - reader (fromJust out) + forkIO $ do +#if !mingw32_HOST_OS + bracket + ( installHandler sigPIPE Ignore Nothing) + (\orig -> installHandler sigPIPE orig Nothing) + $ \_ -> do +#endif + try (writer inp dat) :: IO (Either IOException ()) + hClose inp `catch` const (return ()) + mapM_ waitForProcess pids + reader out -- | A convenience function for when you don't care about the working -- directory, 'pipe\'' uses ".".