Commit 0246baf9 authored by tibbe's avatar tibbe Committed by Herbert Valerio Riedel
Browse files

Implement System.Process.createPipe operation

Neccesary for implementing 'tee' like behavior.

See

 - http://comments.gmane.org/gmane.comp.lang.haskell.libraries/21373
 - https://ghc.haskell.org/trac/ghc/ticket/8943

for more details.
parent 3b107645
{-# LANGUAGE CPP #-}
{-# LANGUAGE CPP, ForeignFunctionInterface #-}
#ifdef __GLASGOW_HASKELL__
#if __GLASGOW_HASKELL__ >= 709
{-# LANGUAGE Safe #-}
......@@ -25,19 +25,6 @@
-- ToDo:
-- * Flag to control whether exiting the parent also kills the child.
{- NOTES on createPipe:
createPipe is no longer exported, because of the following problems:
- it wasn't used to implement runInteractiveProcess on Unix, because
the file descriptors for the unused ends of the pipe need to be closed
in the child process.
- on Windows, a special version of createPipe is needed that sets
the inheritance flags correctly on the ends of the pipe (see
mkAnonPipe below).
-}
module System.Process (
-- * Running sub-processes
createProcess,
......@@ -68,6 +55,9 @@ module System.Process (
terminateProcess,
interruptProcessGroupOf,
-- Interprocess communication
createPipe,
-- * Old deprecated functions
-- | These functions pre-date 'createProcess' which is much more
-- flexible.
......@@ -95,8 +85,14 @@ import System.Exit ( ExitCode(..) )
import System.IO
import System.IO.Error (mkIOError, ioeSetErrorString)
#if !defined(mingw32_HOST_OS)
#if defined(mingw32_HOST_OS)
# include <io.h> /* for _close and _pipe */
# include <fcntl.h> /* for _O_BINARY */
import Control.Exception (onException)
import Foreign.C.Types (CInt(..), CUInt(..))
#else
import System.Posix.Process (getProcessGroupIDOf)
import qualified System.Posix.IO as Posix
import System.Posix.Types
#endif
......@@ -887,3 +883,38 @@ rawSystem cmd args = system (showCommandForUser cmd args)
#else
rawSystem cmd args = system (showCommandForUser cmd args)
#endif
-- ---------------------------------------------------------------------------
-- createPipe
-- | Create a pipe for interprocess communication and return a
-- @(readEnd, writeEnd)@ `Handle` pair.
--
-- /Since: 1.2.1.0/
createPipe :: IO (Handle, Handle)
#if !mingw32_HOST_OS
createPipe = do
(readfd, writefd) <- Posix.createPipe
readh <- Posix.fdToHandle readfd
writeh <- Posix.fdToHandle writefd
return (readh, writeh)
#else
createPipe = do
(readfd, writefd) <- allocaArray 2 $ \ pfds -> do
throwErrnoIfMinus1_ "_pipe" $ c__pipe pfds 2 (#const _O_BINARY)
readfd <- peek pfds
writefd <- peekElemOff pfds 1
return (readfd, writefd)
(do readh <- fdToHandle readfd
writeh <- fdToHandle writefd
return (readh, writeh)) `onException` (close readfd >> close writefd)
close :: CInt -> IO ()
close = throwErrnoIfMinus1_ "_close" . c__close
foreign import ccall "io.h _pipe" c__pipe ::
Ptr CInt -> CUInt -> CInt -> IO CInt
foreign import ccall "io.h _close" c__close ::
CInt -> IO CInt
#endif
......@@ -14,6 +14,8 @@
* Expose `createProcess_` function, and document behavior of `UseHandle` for
`createProcess`. See [issue #2](https://github.com/haskell/process/issues/2).
* New `System.Process.createPipe` operation
## 1.2.0.0 *Dec 2013*
* Update to Cabal 1.10 format
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment