Bug in IO libraries when sending data through a pipe?
20 Mar 2002 22:08:51 +0100
On Mit, 2002-03-20 at 07:00, Jens Petersen wrote:
> Jens Petersen <firstname.lastname@example.org> writes:
> > > The problem is that the child process doesn't receive all the data which
> > > the parent sends. It's as if "hPutStr vonh txt" sends the data lazily
> > > somehow, and "hClose vonh" closes the pipe prematurely.
> > >
> > > It varies from run to run exactly which data gets through. If I cause the
> > > child process to read all its input immediately, the problem doesn't
> > > seem to occur. Normally, it does so gradually, which takes a few seconds.
> > >
> > > I'm using GHC 5.02.2
> > Quite possibly could be a bug. Lazy IO is rather subtle I
> > think, specially when done across pipes. I faced some
> > similar problem with in POpen recently. You can see how I
> > solved it (worked round it?) by comparing the latest release
> > 1.00 with the previous one 0.00.1:
> > http://www.01.246.ne.jp/~juhp/haskell/popenhs/
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.
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 ()
I'm also not sure what this part is supposed to do:
inr <- if (isJust inpt) then
(inr', inw) <- createPipe
hin <- fdToHandle inw
hPutStr hin $ fromJust inpt
return $ Just inr'
Doesn't it write the input data to a pipe which no process reads