Haskell 98: Behaviour of hClose

Glynn Clements glynn.clements@virgin.net
Fri, 20 Sep 2002 22:34:16 +0100


Simon Peyton-Jones wrote:

> Thanks for your input.  If you think it is important, could you please
> propose one or more concrete changes to the wording of the Language
> Report or the Library Report or both.  Then we'll get a better idea of
> what you have in mind.   (Start from the current draft at
> http://research.microsoft.com/~simonpj/haskell98-revised)

1. Regarding the echoing issue, I would simply delete the sentence:

  By default, these input functions echo to standard output. 

from section 7.1 of the report, as:

a) The functions themselves don't do any echoing. The terminal driver
may; but if it does, it will do that regardless of whether or not
these (or any other) functions are called.

b) The terminal driver may do plenty of other things besides echoing. 
Singling out echoing for mention is rather arbitrary; OTOH, a complete
description would occupy a significant amount of space.

2. Regarding the buffering issue, I suggest adding something along the
lines of the following to section 11.4.2 of the library report:

> For a stream which is associated with a terminal device, setting the
> mode to no-buffering will also disable any line-buffering which may
> be performed by the operating system's terminal driver.
> 
> Similarly, setting the mode to line-buffering or block-buffering
> will enable any line-buffering which may be performed by the
> operating system's terminal driver.

However, it was only when analysing the existing behaviour in order to
write that above that I became aware of the second half. This is
potentially more problematic than the first half.

While there isn't much point disabling buffering at the stream level
if it's still being performed by the terminal driver, there *are*
reasons why you might wish to enable buffering at the stream level
without enabling canonical mode (which is what the terminal driver's
"line buffering" actually corresponds to).

E.g. in canonical mode, the EOF character (typically Ctrl-D) will
result in a read() from the OS-level descriptor indicating EOF. In
"raw" mode, the EOF character will be read literally (i.e. '\004' for
Ctrl-D).

IOW, while canonical mode results in line-buffering, it also has other
side-effects.

Another consequence, which has just sprung to mind, is that whereas
the buffering mode of a stream is strictly user-space, and therefore
internal to the program, the terminal driver settings are a property
of the device, and will affect other programs which use that device.

Example: a Haskell program is run on a terminal for which canonical
mode is enabled (which is normally the case), and that program does
"hSetBuffering stdin NoBuffering", thereby disabling canonical mode. 
After the program terminates, canonical mode will still be disabled
for that device.

Similar issues arise in C, i.e. you need to explicitly restore the
terminal settings when the program terminates or is suspended (via
SIGTSTP). However, in C, you would have to have explicitly change the
terminal settings (with e.g. tcsetattr()), whereas Haskell does this
"under the hood".

-- 
Glynn Clements <glynn.clements@virgin.net>