Detecting unused read handles? (was: File handles and pipes)

On Sun, Oct 19, 2008 at 1:44 AM, Brandon S. Allbery KF8NH
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

On 2008 Oct 19, at 2:39, Stephen Hicks wrote:
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?
Not readily, because if the process ends up outputting more than a certain amount (_PIPE_BUF kernel parameter) of data your program will deadlock. I think you need to forkIO and use MVars to synchronize. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH
participants (2)
-
Brandon S. Allbery KF8NH
-
Stephen Hicks