Bug in IO libraries when sending data through a pipe?
Fri, 22 Mar 2002 00:31:35 +0100 (CET)
On 21 Mar 2002, Jens Petersen wrote:
> Volker Wysk <firstname.lastname@example.org> writes:
> > POpen-1.0.0 contains the same bug which I made. It doesn't ensure that
> > the values which are needed after the call of forkProcess, before that
> > of executeFile, are fully evaluated. So, if they are read lazily from a
> > stream, the newly spawned child process reads data from a stream which
> > it shares with its parent, making it disappear from the parent's input.
> > In this situation, this sure isn't intended.
> Perhaps you could give an explicit example?
I haven't tried it, but it's exactly the same thing.
> > Inserting the following lines just before the line "pid <- forkProcess",
> > in POpen.hs, would force the corresponding values to be evaluated, so no
> > data will be lost.
> > seq (length path) $ seq (sum (map length args)) $ return ()
> > when (isJust env) $ seq (sum (map (\(a,b) -> length a + length b)
> > (fromJust env))) $ return ()
> > when (isJust dir) $ seq (length (fromJust dir)) $ return ()
> Hmmm, I don't really see why this is necessary. Don't the
> lazy values of "path", "env" and "dir" just get evaluated
> when they're needed here as normal? (If what you say is
> true though it would be simpler just to use "$!" or "!"s for
> strict evaluation I guess.)
Yes, and that's *after* forkProcess. So when they are computed from
the lazily read contents of a stream, the newly spawned child will read
data from a stream which it shares with its parent.
> > I'm also not sure what this part is supposed to do:
> > inr <- if (isJust inpt) then
> > do
> > (inr', inw) <- createPipe
> > hin <- fdToHandle inw
> > hPutStr hin $ fromJust inpt
> > hClose hin
> > return $ Just inr'
> > else
> > return Nothing
> It returns the output end of a pipe containing the input
> string if one is given.
> > Doesn't it write the input data to a pipe which no process reads
> > from..??
> Nope, "doTheBusiness" dup2's it to the stdin of the subprocess: [...]
But hPutStr, followed by hClose, won't complete until all the input string
has been written, while no process is listening.