Haskell 98: Behaviour of hClose

Simon Peyton-Jones simonpj@microsoft.com
Tue, 24 Sep 2002 09:25:10 +0100


Glynn writes:

| 2. Regarding the buffering issue, I suggest adding something along the
| lines of the following to section 11.4.2 of the library report:
|=20
| > 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.
|=20
| 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.

...and there are several more paragraphs (below).

I conclude that this is all very tricky, and there is no chance of
getting something that is obviously sensible into 11.4.2 in the next few
days.  Again, the swamp beckons, and we've struggled by without any such
words for many years now.  So I propose to do nothing here, rather than
risk making the situation worse.

Thank you to Glynn for trying!   There's a gold medal waiting for
someone who designs a better (portable) I/O library.

Simon



|=20
| 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).
|=20
| 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).
|=20
| IOW, while canonical mode results in line-buffering, it also has other
| side-effects.
|=20
| 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.
|=20
| 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.
|=20
| 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".
|=20
| --
| Glynn Clements <glynn.clements@virgin.net>