Re: [Haskell-cafe] Detecting unused read handles? (was: File handles and pipes)

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
Can the left-fold enumerator described by oleg in http://okmij.org/ftp/Haskell/fold-stream.lhs and with more references at http://okmij.org/ftp/Haskell/ be adapted for reading the output from arbitrary system calls? I.e., to deal with pipes? My intuition says yes but I'm still trying to wrap my head around the whole left fold enumerator approach to io. The text around "We can now test reading from two streams with interleaving:" in the first reference seemed particularly promising to me.
2008/10/19 Stephen Hicks
: On Sun, Oct 19, 2008 at 1:44 AM, Brandon S. Allbery KF8NH
wrote: On 2008 Oct 19, at 1:37, Stephen Hicks wrote:
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:
Pipes are perhaps a bit misnamed: if you want to combine the output of two pipes and funnel it into a third you can't simply "plumb them together", you need to provide code which reads from the output pipes and writes into the input pipe. If you don't care about order, forkIO a thread for each output pipe which reads from the output pipe it's passed and writes to the input pipe. If order is significant, use mapM/forM to run the output-to-input code on each handle in turn.
Thanks a lot - that seems to work very well, and even scales to large amounts of data nicely (and quickly, with Lazy ByteStrings).
I've got one more question now. Suppose I want to do the same thing on the other side, with two processes *receiving* the data. Is there a way to tell whether the first process wants input, and if not, wait for the second process to do anything?
That is, suppose I have something like
do (Just inh1, _, _, p1) <- createProcess (shell "echo 1") { std_in = CreatePipe } -- wait for p1, possibly feeding it some input? (Just inh2, _, _, p2) <- createProcess (shell "cat") { std_in = CreatePipe }
Is there a way to figure out that the "echo 1" process never wanted any input, and therefore not give it any? I looked through all of System.IO and everything seemed to indicate that inh1 was open, even after the process ended. The only indication otherwise was that "hflush inh1" failed with "resource vanished". I guess what I'm asking is I want to "wait until the process p1 is waiting for input and/or terminates", and if it's the latter, move on to the next process in line, before actually doing any hPutStr into the read handles. Is that possible?
Thanks, steve _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Thu, Oct 23, 2008 at 12:38 PM, Thomas Hartman
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
Can the left-fold enumerator described by oleg in
http://okmij.org/ftp/Haskell/fold-stream.lhs
and with more references at http://okmij.org/ftp/Haskell/
be adapted for reading the output from arbitrary system calls? I.e., to deal with pipes? My intuition says yes but I'm still trying to wrap my head around the whole left fold enumerator approach to io.
I found his slides w/notes from defun to be insightful. http://okmij.org/ftp/Streams.html#iteratee grab the talk notes pdf. Jason
participants (2)
-
Jason Dagit
-
Thomas Hartman