ptg10805159
702 Te rminal I/O Chapter 18
handle these signals. Some versions just ignoreSIGINT(saving its previous
action) while ingetpass,resetting the action for this signal to its previous
value beforereturning. This means that any occurrence of the signal while it’s
ignored is lost. Other versions catchSIGINT(saving its previous action) and if
the signal is caught, send themselves the signal with thekillfunction after
resetting the terminal state and signal action. None of the versions ofgetpass
catch, ignore, or blockSIGQUIT, so entering the QUIT character aborts the
program and probably leaves the terminal with echoing disabled.
•Beawarethat some shells, notably the Korn shell, turn echoing back on
whenever they read interactive input. These shells arethe ones that provide
command-line editing and thereforemanipulate the state of the terminal every
time we enter an interactive command. So, if we invoke this program under
one of these shells and abort it with the QUIT character, it may reenable echoing
for us. Other shells that don’t provide this form of command-line editing, such
as the Bourne shell, will abort the program and leave the terminal in no-echo
mode. If we do this to our terminal, thesttycommand can reenable echoing.
•Weuse standardI/O to read and write the controlling terminal. We specifically
set the stream to be unbuffered; otherwise, theremight be some interactions
between the writing and reading of the stream (we would need some calls to
fflush). Wecould have also used unbuffered I/O (Chapter 3), but we would
have to simulate thegetcfunction usingread.
•Westoreonly up to eight characters as the password. Any additional characters
that areentered areignored.
The program in Figure18.18 callsgetpassand prints what we enter to let us verify
that the ERASE and KILL characters work (as they should in canonical mode).
#include "apue.h"
char *getpass(const char *);
int
main(void)
{
char *ptr;
if ((ptr = getpass("Enter password:")) == NULL)
err_sys("getpass error");
printf("password: %s\n", ptr);
/* now use password (probably encrypt it) ... */
while (*ptr != 0)
*ptr++ = 0; /* zero it out when we’re done with it */
exit(0);
}
Figure 18.18 Call thegetpassfunction