On 09 August 2005 20:56, Adam Sampson wrote:
> While tracking down a bug in Ginsu earlier, I found that the cause is
> an unexpected side-effect of the System.Cmd functions: they set FD 0
> (and consequently anything that it's been dupped to, so probably FD 1
> and FD 2 as well) to non-blocking mode. This will break any future
> usage of stdin/stdout that doesn't expect to get an EAGAIN error --
> for example, Ginsu uses the curses library which won't update the
> screen correctly if FD 1 is non-blocking. Worse, this is done before
> the fork(), so the program that's run is also given its FDs in
> non-blocking mode, and will thus suffer the same problems.
>
> It appears that this is a consequence of
> System.Process.Internals.runProcessPosix using "stdin", which sets FD
> 0 to be non-blocking.
GHC puts any file descriptor it uses into O_NONBLOCK mode, so that it
can do I/O multiplexing amongst lightweight threads. The first time you
evaluate stdin, stdout, or stderr they will be put into non-blocking
mode.
We could change runProcessPosix to avoid evaluating stdin, but that
doesn't really solve the problem (and it would change the semantics of
runProcess, albeit in a minor way).
A workaround, if you don't intend to use stdin in your Haskell code
and/or you don't care about concurrency, is to evaluate stdin first and
then explicitly clear the O_NONBLOCK flag:
do stdin `seq` return ()
setFdOption 0 NonBlockingRead False
I think it's a bug in Unix that there's no way to set O_NONBLOCK
privately for a single file descriptor.
It just so happens I came across this same bug recently: someone else
reported that you can't pipe the output of GHC through tee
$ ghc -ddump-simpl Foo.hs -c | tee log
because tee reports a "write error". This is due to GHC putting stdout
into non-blocking mode, again.
If anyone has any good suggestions, I'm all ears.
Cheers,
Simon
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs