ptg10805159
700 Te rminal I/O Chapter 18
Running the program from Figure18.16 gives us
$./a.out < /dev/console 2> /dev/null
fd 0: /dev/console
fd 1: /dev/ttys001
fd 2: not a tty
18.10 Canonical Mode
Canonical mode is simple: we issue a read, and the terminal driver returns when a line
has been entered. Several conditions cause the read to return.
•The read returns when the requested number of bytes have been read. Wedon’t
have to read a complete line. If we read a partial line, no information is lost; the
next read starts wherethe previous read stopped.
•The read returns when a line delimiter is encountered. Recall from Section 18.3
that the following characters areinterpreted as end of line in canonical mode:
NL, EOL, EOL2, and EOF.Also, recall from Section 18.5 that ifICRNLis set and
ifIGNCRis not set, then the CR character also terminates a line, since it acts just
like the NL character.
Of these five line delimiters, one(EOF)is discarded by the terminal driver when
it’s processed. The other four arereturned to the caller as the last character of
the line.
•The read also returns if a signal is caught and if the function is not automatically
restarted (Section 10.5).
Example —getpassFunction
We now examine the functiongetpass,which reads a passwordofsome type from the
user at a terminal. This function is called by thelogin( 1 )andcrypt( 1 )programs. To
read the password, the function must turn offechoing, but it can leave the terminal in
canonical mode, as whatever we type as the passwordforms a complete line.
Figure18.17 shows a typical implementation on a UNIX system.
Thereare several points to consider in this example.
•Instead of hard-wiring /dev/tty into the program, we call the function
ctermidto open the controlling terminal.
•Weread and write only to the controlling terminal and return an error if we
can’t open this device for reading and writing. Thereare other conventions to
use. The version ofgetpassin the GNU C library reads from standardinput
and writes to standarderror if the controlling terminal can’t be opened for
reading and writing. The Solaris version fails if it can’t open the controlling
terminal.