
On Fri, Aug 1, 2014 at 11:07 PM, Chris Myzie
As a workaround, I am able to trick the child haskell process into thinking it's running in an interactive terminal by wrapping it with /usr/bin/script:
We discussed this on IRC the other day. Haskell is doing the same thing that C/C++ stdio / iostreams, and most other buffering systems, do: line buffering on terminal-like devices, block buffering on files and pipes. This is generally expected behavior; although it can be confusing to new programmers, ultimately it is more efficient for most programs. Interactive use like this, especially over pipes, is fairly unusual; normally you're just copying data around /en masse/, and block buffering is far more efficient. Note that line buffering is not and can not be implemented at the kernel level for ordinary files or pipes, so the kernel interface is actually character buffering which is extremely inefficient (at least one context switch per individual character). You might want to search for something like "buffering line block pipes files" to see quite a lot of discussion about it, in pretty much every language you can think of. By the way, more efficient than using script(1) is, as I told you in IRC, to use the mechanism it is using directly: pseudo-terminals (ptys). See http://hackage.haskell.org/package/unix-2.7.0.1/docs/System-Posix-Terminal.h... for the standard pty stuff or http://hackage.haskell.org/package/posix-pty-0.1.0/docs/System-Posix-Pty.htm... for what is claimed to be a simpler interface intended for what you are doing. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net