[Haskell-cafe] Re[2]: Emulating bash pipe/ process lib

Bulat Ziganshin bulatz at HotPOP.com
Fri Feb 10 09:59:35 EST 2006

Hello Simon,

Friday, February 10, 2006, 2:53:25 PM, you wrote:

i'm not very interested to do something fascinating in this area. it
seems that it is enough to do

1) non-blocking read of the entire buffer on input
2) flush buffer at each '\n' at output

that should be enough to implement LineBuffering for everyone except
purists? and for the NoBuffering the same except for flushing after
each output operation?

>>>>DC> "Slow" devices like pipes, sockets etc. get along fine with Handles
>>>>DC> or whatever buffered I/O - as long as you have only one going at a time.
>>>>DC> Multiple input sources - like, say you want to read a process' output
>>>>DC> (unit 1) and diagnostic output (unit 2) separately, and either one has
>>>>DC> the potential to fill up the pipe and block while you're waiting for
>>>>DC> input on the other pipe - buffers at least complicate the dispatching
>>>>DC> mechanics you need for this, if not make it impossible.
>>>>are you tried LineBuffering and NoBuffering? seem that it is developed
>>>>exactly for this case (plus for terminals)
>> DC> That's part of the idea, it helps keep the data out of buffers where
>> DC> select or whatever can't see it.
>> DC> But then you need functions with semantics that really support unbuffered
>> DC> I/O.  When select tells you that the device is readable, you don't know
>> DC> that there is one full line, or how many bytes there are, so hGetLine
>> DC> doesn't apply here, nor would the Haskell equivalent of fread(3) if there
>> DC> were one.  The only thing left is hGetChar - one char, then select, then
>> DC> another.  (And multi-byte chars cause us to worry about this.)
>> when i think how to implementat LineBuffering, i decided that it is
>> the only possible way - read byte a time and see for a '\n'. i don't
>> know how System.IO implemented but i think that it should do the same

SM> Read as much as you can into the buffer without blocking.  Line 
SM> buffering on input is actually implemented exactly the same as block 
SM> buffering.

SM> You might argue that strictly speaking this isn't line buffering, since 
SM> you can get data from the Handle before the end of line is available. 
SM> That's true, but I'd argue this is more useful.  In fact, we changed 
SM> block buffering on input handles so that the input buffer doesn't have 
SM> to be completely full before data can be returned, which is also not 
SM> strict block buffering, but seems more useful.

SM> I suppose conceivably you might want to force a read buffer to be 
SM> completely full so that you could guarantee to read it all without 
SM> blocking, but in that case you might as well use hGetBuf & peekArray. 
SM> Similarly you might want to ensure the buffer contains a complete line 
SM> before starting to read it, but can use hGetLine anyway.

Best regards,
 Bulat                            mailto:bulatz at HotPOP.com

More information about the Haskell-Cafe mailing list