ldterm - STREAMS line discipline module
The ldterm module is a STREAMS module that supplies the
line discipline for terminal devices. This module provides
most of the functions of the terminal interface described
in the /usr/include/termios.h and /usr/include/termio.h
header files for session management, and input and output
processing. However, it does not perform the low-level
device control functions specified by the c_cflag word and
control the speeds defined by the termios structure in the
termios.h header file. Also, some operations require the
cooperation of the modules and drivers pushed below the
ldterm module in the tty or pty stream.
Internally, the ldterm module uses the Extended UNIX Code
(EUC) character encoding scheme. This encoding scheme
enables the module to process multibyte characters as well
as simple 8-bit characters. It correctly handles backspacing
and tab expansion for multibyte characters.
The ldterm module provides standard terminal operation
consistent with the behavior specified by POSIX 1003.1. It
also provides compatibility with the behavior of the BSD
line discipline module used in Tru64 UNIX (see the tty(7)
reference page), including System V Interface Definition
(SVID) compatibility.
STREAMS Messages [Toc] [Back]
The ldterm module processes various types of STREAMS messages.
The line discipline will act on any of the following
message types. Any others that the module receives,
however, are passed on to the next module.
Read Put Routine [Toc] [Back]
The ldterm read put routine processes the following
STREAMS messages: If FLUSHR is set, the read put routine
flushes the read queue, discards characters in the input
message buffers, and discards any partially buffered
multibyte characters. Then, it forwards the message
upstream. The read put routine processes the message
according to POSIX rules for processing BREAK events, parity
errors, and framing errors. If there is no data in the
message, the message is assumed to represent an input
BREAK event, which is represented by a framing error with
a character value of 0 (zero). If there is data in the
message, the data value is an integer that indicates the
occurrence of an input BREAK event, or a character
received with a parity or framing error. The low-order 8
bits of the data value is the byte that was read. If the
TTY_PE flag is set in the higher-order bits of this integer,
then a parity error was detected. If the TTY_FE flag
is set in the higher-order bits of this integer, a framing
error was detected.
After reading the data value, the read put routine
discards the message. The read put routine processes
the message according to the POSIX 1003.1
specification, using multibyte processing for tab
expansion and backspacing, as appropriate.
It generates echo characters and places them in the
output buffer to be sent downstream to the write
queue. While processing incoming data, it scans for
START and STOP characters and sends M_START/M_STOP
messages downstream to the write queue, if needed.
The read queue high-water mark is POSIX_MAX_INPUT/2
and the low-water mark is POSIX_MAX_INPUT/5. If
the total number of buffered input characters is
more than the high-water mark and IXOFF is set, the
read put routine sends an M_STOPI message downstream.
When the queue reduces its backlog below
the low water mark, it sends an M_STARTI message
downstream.
If the number of buffered input characters reaches
POSIX_MAX_INPUT, and the IMAXBEL flag is set, the
read put routine discards new input characters and
sends a BEL character (Ctrl-G) downstream. If IMAXBEL
is not set, it flushes the input queue.
If the ISIG flag is set, the read put routine sends
M_PCSIG messages upstream when the appropriate signal
characters are encountered. Then, it discards
the characters.
If a character matching c_cc[VDISCARD] is encountered,
and the IEXTEN flag is set, the read put
routine sends an M_FLUSH (FLUSHW) message upstream
to flush all write queues. The M_FLUSH message is
reflected by the stream head and sent downstream
through all the write queues.
If the character signifies the logical termination
of input, the read put routine sends the currently
buffered characters upstream to the stream head.
Logical termination of input depends on the state
of the ICANON flag. If ICANON is set, the ldterm
module is in canonical input mode. In that case,
the read put routine logically terminates input at
the end of a line of input. Canonical line termination
characters are NEWLINE, EOF, EOL, and EOL2.
If ICANON is clear, the ldterm discipline module is
in noncanonical or raw input mode. In that case,
the read put routine terminates input when at least
VMIN bytes are present in the input message buffer
or the timer specified by VTIME expires. If the
message acknowledges the termios TIOCGETA command,
the read put routine copies the c_cflag and speeds
information, which is sent by the console driver
downstream, from the message into the internal
termios structure. Then, it copies the internal
termios structure into the message.
If the message acknowledges one of the termios set
commands TIOCSETA, TIOCSETAW, or TIOCSETAF, the
read put routine copies all of the data from the
message into the internal termios structure. If the
message acknowledges an TIOCOUTQ command, the read
put routine records the number of bytes in the
ldterm module's internal output buffer in the message
and forwards the message upstream.
After this processing is done, the read put routine
determines if the I/O control command was originally
a BSD or System V I/O control command that
was converted to a termios command by the write
service routine. If so, it restores the original
data so that the message acknowledges the original
I/O control command. Then, it forwards the message
upstream.
Write Service Routine [Toc] [Back]
The ldterm write service routine processes messages that
may be delayed due to STREAMS flow control. This message
was sent by the driver to communicate changes in the
driver's state. In the STREAMS tty and pty subsystems, the
structure of M_CTL messages is the same as that of M_IOCTL
messages. The M_CTL message block points to a message
buffer containing an iocblk data structure. The ioc_cmd
member of this structure contains a command, just as it
does in an M_IOCTL message. The b_cont member of the
M_CTL message block contains a pointer to an M_DATA message
block, which contains data associated with the M_CTL
message.
The read put routine processes M_CTL messages containing
the following commands: The driver sends
this message to reflect an asynchronous change in
its winsz structure settings. The read put service
routine copies the winsz structure into its internal
structure. It then frees the associated M_CTL
message using the freemsg function. The driver
sends this message to reflect an asynchronous
change in its termios flag settings. The read put
service copies the termios structure from the
attached M_DATA message block into its internal
termios structure. Then, it frees the associated
M_CTL message using the freemsg() function.
Write Put Routine [Toc] [Back]
The ldterm write put routine processes the following
STREAMS messages. Messages not listed here are simply forwarded
downstream. If FLUSHW is set, the write put routine
flushes the write queue and discards any buffered
output data. Then, it forwards the message downstream.
The write put routine queues the message to the write
queue for later processing. The write put routine validates
the format of the M_IOCTL message and checks for
known commands. If the message format is invalid, it
turns the M_IOCTL message into an M_IOCNAK message, and
returns the message upstream. If the I/O control command
is not recognized, it forwards the M_IOCTL message downstream
for processing by other modules.
The write put routine determines if the command is
one that must be processed in the proper sequence
relative to M_DATA messages. If so, it queues the
M_IOCTL message to the write queue for later processing
by the write service routine. Commands
that require processing in sequence are as follows:
TIOCSETAW TIOCSETAF TCSETAW TCSETAF TCSBRK Otherwise,
the module's write put routine processes the
command immediately. Detailed descriptions of the
preceding ioctl commands are provided in The ioctl
Commands. This message is sent by the stream head
to notify downstream modules when an application
has issued a read request and there is not enough
data queued at the stream head to satisfy the
request. The M_READ message contains the number of
characters requested by the application.
If the module is in noncanonical input mode, and
VTIME is positive, the write put routine starts an
input timer. When the timer expires, it sends all
buffered input upstream. Then, it forwards the
M_READ message downstream. The write service routine
processes the data according to the POSIX
1003.1 specification output flags. It sends the
processed characters downstream to the driver when
the output queue fills up and all of the data is
processed. Some I/O control commands must wait
until output drains before they are processed.
M_IOCTL messages containing these commands are
queued on the write queue so that the write service
routine processes them in the correct sequence relative
to preceding data. A list of these commands
is provided in the Write Put Routine section. Processing
of the individual I/O control commands is
described in the The ioctl Commands section of this
reference page and in the tty and termios reference
pages.
The ioctl Commands [Toc] [Back]
The ldterm module acts on three categories of ioctl commands:
Primary I/O control commands BSD4.3 compatibility
I/O control commands System V Interface Definition compatibility
I/O control commands
Primary I/O Control Commands
The ldterm module acts on the following primary I/O commands:
The ldterm module does nothing but reply to this
command. In a BSD system, the command is used to set the
current line discipline type. It does not have much meaning
in a STREAMS environment, because line discipline modules
are changed by popping the current module from the
stream and pushing a different one onto the stream. In a
BSD system, this command is used to get the current line
discipline type. The command does not have much meaning in
a STREAMS environment. The ldterm module replies with a
value of 0 (zero). The ldterm module generates M_FLUSH
messages and flushes the appropriate internal message
buffers. Then, it acknowledges the message with M_IOCACK.
The ldterm module sets or resets the TS_ASYNC state. Then,
it forwards the message to the next module. When the
ldterm module receives this command in an M_IOCTL message,
it forwards the command downstream. When the module
receives the M_IOCACK message in the read queue, it adds
the number of characters in the output buffer to the reply
value in the M_IOCACK message and forwards the message
upstream. When the ldterm module receives any of these
commands in an M_IOCTL message, it forwards them downstream.
When it receives the M_IOCACK message in the read
queue, it copies the POSIX termios information from the
message into the internal termios structure and forwards
the message upstream. The ldterm module forwards the
M_IOCTL message downstream. When it receives the M_IOCACK
message in the read queue, it copies the CLOCAL flags and
speeds from the message into the internal termios structure.
Then, it copies the entire structure into the
M_IOCACK message and forwards the message upstream. This
command sets the window size variable. The ldterm module
does not use this variable, but maintains it here for any
needed replies to TIOCGWINSZ commands. The module forwards
the message downstream. When the ldterm module receives
this command, it returns the window size variable that was
last set by the last TIOCSWINSZ command. This command
sets the termios HUPCL flag to indicate that the terminal
line should be disconnected when the last file descriptor
associated with that line is closed. The ldterm module
converts the command into a compatible termios I/O control
command by sending an M_IOCTL message containing the TIOCSETA
command with current termios settings downstream.
This command stops output. The ldterm module sends an
M_STOP message downstream. The command restarts output.
If the terminal was stopped, the ldterm module sends an
M_START message downstream. This command sets the EUC
character widths. The ldterm module forwards the message
to the next module. This command returns the EUC character
widths. This command set the break condition on a
line. The ldterm module sends an M_BREAK message containing
a value of 1 as data to the driver, then replies with
M_IOCACK. This command clears the break condition on a
line. The ldterm module sends an M_BREAK message containing
a value of 0 (zero) as data to the driver, then
replies with M_IOCACK.
BSD4.3 Compatible I/O Commands
The ldterm module acts on the following I/O commands,
which are compatible with the BSD I/O environment: This
command retrieves the hardware bits of the sgttyb control
structure. The ldterm module converts the message to a
termios M_IOCTL so that the driver does not have to know
about the sgttyb control structure. Then it forwards the
termios M_IOCTL message to the driver. The original I/O
control command and M_IOCTL message are stored for use on
the M_IOCACK message. These commands set the sgttyb
information. The ldterm module converts the message to a
termios M_IOCTL so that the driver does not have to know
about the BSD or System V I/O control structures. Then, it
forwards the termios M_IOCTL message with a corresponding
termios command. The original I/O control command and
M_IOCTL message are stored for use on the M_IOCACK message.
The ldterm module returns the tchars information in
a termios structure. This command sets the tchars information.
The ldterm module converts the message to a
termios M_IOCTL so that the driver does not have to know
about the BSD or System V I/O control structures. Then, it
forwards the termios M_IOCTL message with a corresponding
termios command. The original I/O control command and
M_IOCTL message are stored for use on the M_IOCACK message.
The ldterm module returns the ltchars information
in a termios structure. This command sets the ltchars
information. The ldterm module converts the message to a
termios M_IOCTL so that the driver does not have to know
about the BSD or System V I/O control structures. Then,
it forwards the termios M_IOCTL message with a corresponding
termios command. The original I/O control command and
M_IOCTL message are stored for use on the M_IOCACK message.
The ldterm module returns the BSD4.3 flags information
in a termios structure. These commands set the
BSD4.3 flags information. The ldterm module converts the
message to a termios M_IOCTL, then forwards the termios
M_IOCTL message with a corresponding termios command. It
stores the original I/O control command and M_IOCTL message
to be used on the M_IOCACK message. This I/O control
command is meaningless in a STREAMS environment. The
ldterm module replies with a value of 0 (zero). This I/O
control command is meaningless in a STREAMS environment.
The ldterm module does nothing and replies.
System V Interface Definition Compatibility I/O Commands
The ldterm module acts on the following I/O commands,
which are compatible with the SVID I/O environment: This
command results in the same action as TIOCSTOP or TIOCSTART,
depending on the argument. This command has the
same behavior as the TIOCFLUSH command. The ldterm module
converts the command to a termios M_IOCTL message, then
forwards the message with the TIOCGETA command. The original
I/O control command and M_IOCTL message are stored to
be used on the M_IOCACK message. When it receives the
matching M_IOCACK message, the ldterm module processes it
as for a TIOCGETA command, then converts the termios
information into the System V termio information and
replies. These commands set the System V termio information.
The ldterm module converts the command to a termios
M_IOCTL message, then forwards the message with a corresponding
termios command. The original I/O control command
and M_IOCTL message are stored for use on the M_IOCACK
message. The ldterm module forwards this command downstream
to be handled by the driver.
File: termios(4)
Interfaces: eucioctl(7), tty(7)
ldterm(7)
[ Back ] |