packages feed

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 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 ".".