tags:

views:

247

answers:

2

I am writing a program that runs an external sub process interactively and I need the contents of the output handle to be output to stdout as soon as it is available. I have tried something like this:

main = do processInfo <- createProcess (proc "ghci" []){std_out = CreatePipe,
                                                    std_in  = CreatePipe }
       case processInfo of
          (Just hIn, Just hOut, _, _) -> do mainloop hIn hOut
                                          hClose hIn
                                          hClose hOut
       _                              -> do error "Unable to start process"

mainloop :: Handle -> Handle -> IO ()
mainloop inh outh = 
    do ineof <- hIsEOF outh
       if ineof
          then return ()
          else do inpStr <- hGetLine outh
                  putStrLn inpStr
                  mainloop inh outh

But this doesn't work since it only recognizes output line by line, so any output on the processes output handle that isn't terminated by a newline doesn't show up. I have tried the same thing with hGetContents but it produces the same result. I have read through the documentation of both System.Process and System.IO and haven't really found anything conclusive.

+1  A: 

I'm very much a Haskell newbie, but I remember coming across an example recently of processing input character-by-character. Is hSetBuffering possibly what you are looking for?

Daniel Pratt
+2  A: 

hSetBuffering is what you're looking for, the default (on Unix at least) is line buffering. Use it on the stdin before starting the main loop

hSetBuffering hIn NoBuffering

and optionally also on the output handle if you want to see the results immediately on the output side. Note, however, that disabling buffering can quite drastically decrease performance.

nominolo
Thank you, I didn't even think of changing the buffering mode on stdin/stdout.
devonrt
It's worth noting that the default on Windows is different to the default on Linux so it's worth setting the buffering type anyway to get consistent behaviour.
Porges