[Haskell-cafe] File handles and pipes

Stephen Hicks sdh33 at cornell.edu
Sun Oct 19 01:37:56 EDT 2008


Hi,

I'm trying to understand how to get pipes working in Haskell, in
particular with the revamped System.Process (though I've tried similar
experiments with System.Posix.IO and Control.Concurrent).
Specifically I'm trying to concatenate the output of two system calls
into the input of a third.  The following code does not get the job
done:

> import Data.Maybe ( fromJust )
> import System.IO
> import System.Process

> sink :: String -> IO (Handle,ProcessHandle)
> sink s = do let p = (shell s) { std_in = CreatePipe }
>             (mh, _, _, ph) <- createProcess p
>             return (fromJust mh,ph)

> source :: String -> Handle -> IO ()
> source s h = do let p = (shell s) { std_out = UseHandle h,
>                                     close_fds = False }
>                 (_, _, _, ph) <- createProcess p
>                 waitForProcess ph
>                 return ()

> main :: IO ()
> main = do (h,p) <- sink "sort"
>           source "df" h
>           source "df -h" h
>           waitForProcess p
>           return ()

When I run this, I see that the filehandle h is closed after the first
df, so the output only has one of the two df's included in it.  I
tried also System.Posix.IO (createPipe, fdToHandle, dup) to make this
work, but that gave a "read failed" error.  Is there any way to get
this done...?  In general, given a handful of system calls (and/or
read/write handles), is there a way to combine them all together?  (I
also tried using forkIO on my own function pipe :: [Handle] -> Handle
-> IO (), which does what you'd expect given multiple read handles and
a single write handle, but couldn't get any output from that at
all...)

Any help is appreciated,
steve


More information about the Haskell-Cafe mailing list