Bug in IO libraries when sending data through a pipe?

Volker Wysk post@volker-wysk.de
Sun, 10 Mar 2002 16:48:52 +0100 (CET)


There seems to be a bug in the IO libraries. I'm using the following
procedure to call an external program and send it data through a pipe.

pipeto :: String -> String -> [String] -> IO ()
pipeto txt prog par = do
    catch (do
        -- create pipe
        (zu, von) <- createPipe
        vonh <- fdToHandle von
        hSetBuffering vonh NoBuffering

        mpid <- forkProcess
        case mpid of
           Nothing -> do   -- child
              -- connect pipe's read end to stdin
              -- and close its write end
              dupTo zu (intToFd 0)
              fdClose zu
              hClose vonh

              executeFile prog True par Nothing
              ... -- (print error message)
           Just pid -> do   -- parent
              fdClose zu          -- close pipe's read end
              -- ** here **
              hPutStr vonh txt    -- write text to forked process
              hClose vonh         -- close pipe's write end
              -- wait for child process to finish
              (Just ps) <- getProcessStatus True True pid
              if ps == Exited ExitSuccess
                  then return ()
                  else ...) -- (error message)
       (\err -> ...) -- print error message

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