The TTY layer
href="tty layer - The user perspective_file/style.css" rel=stylesheet>
tty layer - The user perspective
References:W.R. Stevens, "Adavnced Programming in the UNIX
environment", Addison-Wesley 1993 clear=all>
width=240 align=right> The user perspective of the tty layer is the terminal
I/O. This is a complex topic because it is used to control a lot of different
devices (terminals, modem, serial lines, ...). The logical view is shown in the
figure on the side. Between the user input/output, mediated by the device
drivers, and the process read/write, there is the tty layer, which buffers the
data in two queues. Both queues have a maximum size. When the output queue is
full the process is put to wait. When the input queue is full characters are
lost. If echo is enabled the input characters are echoed on the output queue.
The kernel characteristics of a tty are contained in a struct
termio (defined in include/asm/termios.h). This contains
c_iflag, the input mode flags;
c_oflag, the output mode flags;
c_lflag, the local mode flags;
c_cflag, the control mode flags;
c_line, line discipline type (this is not seen by the user);
c_cc, an array of control characters A similar
structure exists (termios) which differ only in the typing of the
fields (POSIX like). Userland has the struct termios (define in
/usr/include/bits/termios.h) which contains also i/o speed fields. The values of
the flags bits and the special characters are listed in the tables below.
c_iflag
BRKINT
generate SIGINT on BREAK
ICRNL
map CR to NL on input
IGNBRK
ignore BREAK
IGNCR
ignore CR
IGNPAR
ignore characters with parity errors
IMAXBEL
ring bell on input when the input queue is full
INLCR
map NL to CR
INPCK
enable input parity checking
ISTRIP
strip eighth bit off input characters
IUCLC
map uppercase to lowercase on input
IXANY
exable any character to restart output
IXOFF
enable start/stop input flow control
IXON
enable start/stop output flow control
PARMRK
mark parity errors
c_oflag
BSDLY
backspace delay mask
CRDLY
CR delay mask
FFDLY
formfeed delay mask
NLDLY
NL delay mask
OCRNL
map CR to NL on output
OFDEL
fill is DEL (else is NUL)
OFILL
use fill characters for delay
OLCUL
map lowercase to uppercase on output
ONLCR
map NL to CR-NL (this is CRMOD)
ONLRET
NL performs CR function
ONOCR
no CR output at column 0
ONOEOT
discard EOF (^D) on output
OPOST
perform output processing
OXTABS
expand tabs to spaces
TABDLY
horizontal tab delay mask
VTDLY
vertical tab delay mask
c_cflag
CCTS_OFLOW
CTS flow control of output
CIGNORE
ignore control flags
CLOCAL
ignore modem status line
CREAD
enable receiver
CRTS_IFLOW
RTS flow control on input
CSIZE
character size mask
CSTOPB
send two stop bits (else send one)
HUPCL
hangup on last close
MDMBUF
flow control output via Carrier
PARENB
parity enable
PARODD
parity is odd (else is even)
c_lflag
ALTWERASE
use alternate WERASE algorithm
ECHO
enable echo
ECHOCTL
echo control characters as ^Char
ECHOE
visually erase characters
ECHOK
echo KILL (by erasing the entire line)
ECHOKE
visual erase for KILL
ECHONL
echo NL
ECHOPRT
visula erase mode for hardcopy
FLUSHO
output being flushed
ICANON
canonical input
IEXTEN
enable extended input character processing
ISIG
enable terminal-generated signals
NOFLSH
disable flush after interrupt or quit
NOKERNINFO
no kernel output from STATUS
PENDIN
retype pending input
TOSTOP
send SIGTTOU for background output
XCASE
canonical upper/lower presentation
Special characters
subscript
enabled by
CR
carriage return
-
ICANON
EOF
end-of-file
VEOF
EOL
end-of-line
VEOL
EOL2
alternate end-of-line
VEOL2
ERASE
backspace one character
VERASE
KILL
VKILL
erase line
NL
linefeed
-
REPRINT
reprint all input
VREPRINT
STATUS
status request
VSTATUS
WERASE
backspace one word
VWERASE
START
resume output
VSTART
IXON / IXOFF
STOP
stop output
VSTOP
DSUSP
delayed suspend (SIGTSTP)
VDSUSP
ISIG
INTR
interrupt signal (SIGINT)
VINTR
QUIT
quit signal (SIGQUIT)
VQUT
SUSP
suspend signal (SIGTSTP)
VSUSP
DISCARD
discard output
VDISCARD
IEXTEN
LNEXT
literal next
VLNEXT
The user control of the tty can be done with the ioctl()
function, but its last argument depends on the action being performed. This
makes type checking impossible. Therefore POSIX defines 12 functions,
tcsetattr, tcgetattr: to set/get the tty
attributes;
cfgetispeed, cfsetispeed,
cfgetospeed, cfsetospeed: for the i/o speeds (baud
rate);
tcdrain, tcflow, tcflush and
tcsendbreak are line control functions;
tcgetpgrp and tcsetpgrp: get/set foreground
process group ID.
Canonical modeCanonical mode (cooked) is simple, from the user
point of view: reads are linewise, ie, the read() call returns when a complete
line has been entered by the device driver. A line is complete when one of the
folloing delimiters is entered: NL, EOL, EOL2, EOF (and CR if ICRNL is set and
INGCR is not set). Note that EOF is not returned with the read.
Noncanonical modeThis is set by turning off ICANON. The input
characters are not assembled into lines. These special characters are not
processed: ERASE, KILL, EOF, NL, EOL, EOL2, CR, REPRINT, STATUS, WERASE. The two
entries c_cc[VMIN] and c_cc[VTIME] determine the
behaviour of the read(). There are four cases:
MIN=0
TIME=0
read() returns immediately with whatever data are available (from 0 if
none, to the maximum number requested in the call)
MIN=0
TIME>0
read() returns between 1 and the requested number if there are data
before the time expires; it returns 0 if the time expires
MIN>0
TIME=0
read() returns between 1 and the requested number when there are data
available (may wait forever)
MIN>0
TIME>0
read() returns between MIN and the number requested before the time
expires, or or between 1 and MIN-1 if the time expires. It can block
forever if there are no data
There are two noncanonical modes (i am aware of), cbreak and raw.
cbreak
ECHO and ICANON off
MIN=1, TIME=0
raw
ECHO, ICANON, IEXTEN and ISIG off
BRKINT, ICRNL, INPCK, ISTRIP, IXON off
CSIZE, PARENB and OPOST off
CS8 (set 8-bit characters)
MIN=1, TIME=0
To conclude this summary of terminal I/O look at this example from Steven's
book. href="http://www.geocities.com/marco_corvi/games/lkpe/tty/tty_raw.c">tty_raw.c,
set a tty in raw modeMarco Corvi -
2003
language=JavaScript>var PUpage="76001084"; var PUprop="geocities";
src="tty layer - The user perspective_file/pu5geo.js">
src="tty layer - The user perspective_file/ygIELib9.js">
var yviContents='http://us.toto.geo.yahoo.com/toto?s=76001084&l=NE&b=1&t=1057747208';yviR='us';yfiEA(0);
src="tty layer - The user perspective_file/mc.js">
src="tty layer - The user perspective_file/geov2.js">
geovisit();
src="tty layer - The user perspective_file/visit.gif" width=1
border=0> src="tty layer - The user perspective_file/serv.gif" width=1>