TIP 160: Improvements to Terminal and Serial Channel Handling

Login
Bounty program for improvements to Tcl and certain Tcl packages.
State:          Final
Type:           Project
Tcl-Version:    8.7
Vote:           Done
Post-History:	
Author:         Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
Created:        17-Oct-2003
Tcl-Branch:     tip-160
Votes-For:      DKF, JN, SL, AK
Votes-Against:  none
Votes-Present:  FV 

Abstract

Terminals, consoles and other kinds of serial lines have other capabilities and requirements that are not currently controllable using Tcl. This TIP adds new options to fconfigure to allow these advanced capabilities to be supported within Tcl in a straight-forward way.

Serial Line Discard Control

Serial lines are much slower devices than virtually anything else on a modern computer, and it is quite possible for them to take a very long time to read data. Often, making sure all the data gets across is important. But this is not universally the case, and sometimes it is more useful to discard the output bound for the serial line that is pending in the operating system's own buffers. This can't be enabled by default in any configuration though, since there is no trivial way to distinguish automatically between terminals that are having debugging information written to them and serial lines that were opened for data manipulation and where closing quickly is desirable (you can't tell them apart even by device major/minor numbers due to the way that /dev/tty is aliased inside the kernel on many Unixes.) This was even the subject of a subtle bug (#525783) in TIP 35. But since it is still useful, having it controllable by an explicit option is useful.

I propose a new option for serial channels on all platforms: -closemode. This will have three legal values:

  • default: Any flushing or draining of the channel will be up to the OS to perform; Tcl will not request anything special. This is the current behavior; other behaviours will have to be explicitly selected.

  • drain: Closing the channel will result in a delay until the entire contents of the OS buffers are written.

  • discard: Closing the channel will result in any data in the OS buffers to be thrown away. This can result in data that is being written by other processes being lost. This can result in data that is being written by other channels being lost if the OS has chosen to unify its buffers for the underlying file descriptors.

This option will be supported on all platforms where the underlying serial API is sufficiently capable. Where it is not supported, the option will not be defined on serial channels.

Echo and Cooking Control

Terminals (on Unix) and consoles (on Windows) have a number of modes of operation. Two of the most useful things that can be set relate to echoing and cooking.

Echoing is fairly simple to understand. If a terminal has echoing turned on, every character read is written to the terminal automatically without any action from the program reading from the terminal. Most of the time this is a good thing as people want to see what they have typed, but sometimes it is not so good. Examples include where someone is typing in a password (when they also want their lines cooked) and where an application is being controlled by single key-presses (which is a case where neither echoing or cooking are desirable, with echoing being a problem because the key press is causing a different set of visible changes in the program's output.)

Cooking is also fairly simple. A terminal is producing cooked input when it is working in simply-editable line-at-a-time mode. When the terminal isn't in cooked mode, it delivers raw input directly and immediately to the program. Cooked input is the default and is useful for a lot of purposes, but sometimes (when the application wants to use single key-presses to control it) raw input is definitely preferable. Example uses of raw input include text editors (such as vi or emacs) or terminal-based menu systems.

I propose supporting these operation modes within Tcl through a single new option to the fconfigure command (to definitely be implemented on Unix serial channels — because that is the type of stdin in a normal interactive session — and suitably on other platforms if possible): -inputmode. This will have four legal values:

  • normal: This will turn on both echoing and cooking of input, and can be considered to be the default configuration for all terminals.

  • password: This will turn off echoing but leave cooking turned on. Note that on at least one platform (macOS) this additionally changes the cursor in the terminal.

  • raw: This will turn off both echoing and line-cooking. Users may want to also use the binary encoding when choosing this option.

  • reset: This restores the channel to whatever configuration it was in when it was opened. This is never reported when queried for; it is a write-only value.

I'm not aware off-hand of any use-cases for echoed raw mode. While there is theoretically a problem due to cross-talk between channels (similar to that which was observed with the rationale for the -closemode option), it is practically unlikely to be one since applications that take parsed input from several serial lines are very rare.

Officially, the default value of the -inputmode option will be system- and configuration-dependant, since users can use the stty program to configure their terminals prior to calling Tcl.

If the user changes the -inputmode, the mode that was present when the channel was opened will be restored when Tcl closes the channel, just as if the reset option is used.

Terminal Size

It is common for terminals to be able to be of variable size. To accommodate this, terminals (on Unix) and consoles (on Windows) will gain a read-only fconfigure option, -winsize, that when read will return a two element list with the current width (first element) and height (second element) of the terminal/console.

Platform Portability

On Unix, terminals cover both serial lines and consoles, and so gain all options.

On Windows, serial lines and consoles are separate channel types, so -closemode is only supported on serial lines, and -inputmode and -winsize are only supported on consoles.

Copyright

This document has been placed in the public domain.

History