STREAMS-Based Terminal Subsystem
This chapter describes how a terminal subsystem is set up and how interrupts are handled. Different protocols are addressed, as well as canonical processing and line discipline substitution.
Overview of Terminal Subsystem
STREAMS provides a uniform interface for implementing character I/O devices and networking protocols in the kernel. The SunOS 5.6 software implements the terminal subsystem in STREAMS. The STREAMS-based terminal subsystem (Figure C-1) provides many benefits:
Reusable line discipline modules. The same module can be used in many streams where the configuration of these streams may be different.
Line-discipline substitution. Although the Solaris operating environment provides a standard terminal line-discipline module, another one conforming to the interface can be substituted. For example, a remote login feature may use the terminal subsystem line discipline module to provide a terminal interface to the user.
Internationalization. The modularity and flexibility of the STREAMS-based terminal subsystem enables an easy implementation of a system that supports multiple-byte characters for internationalization. This modularity also allows easy addition of new features to the terminal subsystem.
Easy customizing. Users may customize their terminal subsystem environment by adding and removing modules of their choice.
The pseudo-terminal subsystem. The pseudo-terminal subsystem can be easily supported (this is discussed in more detail in the section "STREAMS-based Pseudo-Terminal Subsystem").
Merge with networking. By pushing a line discipline module on a network line, you can make the network look like a terminal line.
Figure C-1 STREAMS-based Terminal Subsystem
The initial setup of the STREAMS-based terminal subsystem is handled with the ttymon(1M) command within the framework of the Service Access Facility (autopush feature). See "STREAMS Administrative Driver" for more information.
The STREAMS-based terminal subsystem supports termio(7I), the termios(3C) specification of the POSIX standard, multiple-byte characters for internationalization, the interface to asynchronous hardware flow control and peripheral controllers for asynchronous terminals. XENIX and BSD compatibility can also be provided by pushing the ttcompat module.
To use shl with the STREAMS-based terminal subsystem, the sxt driver is implemented as a STREAMS-based driver. The sxt feature is being discontinued and might not be available, so try to use the job-control mechanism instead of sxt. Note that both shl and job control should not be run simultaneously.
Master Driver and Slave Driver Characteristics
The master driver and slave driver have the following characteristics:
Each master driver has one-to-one relationship with a slave device based on major/minor device numbers.
Only one open is allowed on a master device. Multiple opens are allowed on the slave device according to standard file mode and ownership permissions.
Each slave driver minor device has a node in the file system.
An open on a master device automatically locks out an open on the corresponding slave driver.
A slave cannot be opened unless the corresponding master is open and has unlocked the slave.
To provide a TTY interface to the user, the ldterm and ptem modules are pushed on the slave side.
A close on the master sends a hang up to the slave and renders both streams unusable, after all data have been consumed by the process on the slave side.
The last close on the slave side sends a zero-length message to the master but does not sever the connection between the master and slave drivers.
Line-Discipline Module
A STREAMS line-discipline module called ldterm is a key part of the STREAMS-based terminal subsystem. Throughout this chapter, the terms line discipline and ldterm are used interchangeably and refer to the STREAMS version of the standard line discipline and not the traditional character version. ldterm performs the standard terminal I/O processing traditionally done through the linesw mechanism.
The termio(7I) and termios(3C) specifications describe four flags that are used to control the terminal:
c_iflag defines input modes
c_oflag defines output modes
c_cflag defines hardware control modes
c_lflag defines terminal functions used by ldterm(7M)
To process these flags elsewhere (for example, in the firmware or in another process), a mechanism is in place to turn the processing of these flags on and off. When ldterm(7M) is pushed, it sends an M_CTL message downstream that asks the driver which flags the driver will process. The driver sends back that message in response if it needs to change the ldterm default processing. By default, ldterm(7M) assumes that it must process all flags except c_cflag unless it receives a message indicating otherwise.
Default Settings
When ldterm is pushed on the stream, the open routine initializes the settings of the termio flags. The default settings are:
c_iflag = BRKINT|ICRNL|IXON|IMAXBEL c_oflag = OPOST|ONLCR|TAB3 c_cflag = CREAD|CS8|B9600 c_lflag = ISIG|ICANON|ECHO|ECHOK|IEXTEN|ECHOE|ECHOKE | ECHOCTL |
In canonical mode (ICANON flag in c_lflag is turned on), read from the terminal file descriptor is in message non-discard (RMSGN) mode (see streamio(7I)). This implies that in canonical mode, read on the terminal file descriptor always returns at most one line, regardless of how many characters have been requested. In non-canonical mode, read is in byte-stream (RNORM) mode. The flag ECHOCTL has been added for SunOS 4.1 compatibility.
For information on user-configurable settings, see termio(7I).
Module open and close Routines
The open routine of the ldterm(7M) module allocates space for holding the TTY structure (see ldtermstd_state_t in ldterm.h) by allocating a buffer from the STREAMS buffer pool. The number of modules that can be pushed on one stream, as well as the number of TTYs in use, is limited. The number of instances of ldterm that have been pushed is limited only by available memory. The open also sends an M_SETOPTS message upstream to set the stream head high-water and low-water marks to 1024 and 200, respectively. These are the current values.
The ldterm module identifies itself as a TTY to the stream head by sending an M_SETOPTS message upstream with the SO_ISTTY bit of so_flags set. The stream head allocates the controlling TTY on the open, if one is not already allocated.
To maintain compatibility with existing applications that use the O_NDELAY flag, the open routine sets the SO_NDELON flag on in the so_flags field of the stroptions(9S) structure in the M_SETOPTS message.
The open routine fails if there are no buffers available (so it cannot allocate the internal state structure) or when an interrupt occurs while waiting for a buffer to become available.
The close routine frees all the outstanding buffers allocated by this stream. It also sends an M_SETOPTS message to the stream head to undo the changes made by the open routine. The ldterm(7M) module also sends M_START messages downstream to undo the effect of any previous M_STOP messages.