Input Minus the Echo

The prompt appears in the terminal window: Type your password. As you type the password, text doesn’t appear on the screen. Yes, the program is using stream I/O. So how do you code standard input that doesn’t output characters?

The answer is brought to you by the term echo.

The terminal window’s ancestor is the teletype machine, which is why a terminal window’s device name begins with tty. Streaming I/O has its foundations in telecommunications and many of a terminal’s configuration options come from that domain. One of them is the echo.

In telecommunications, when a character is sent from one device to another it can also be sent to the display. It need not be, but the user expects it. This feature is called echo or local echo. Figure 1 illustrates.

Simplex Communications

Figure 1. In simplex communications, output text must be echoed to the display. For duplex communications, the other system returns the output character. (Click image to view animation.)

A character received is sent to the display be default, as shown in Figure 1. But for the sending terminal, local echo is an option. In fact, remnants of this option are seen in MS-DOS batch files, with the command ECHO OFF, which suppresses echoing of commands to the display while the batch file runs.

When you type a password in a terminal window, the programmer disables local echo. After text is input and processed, local echo is restored. The programmer resets the echo by programming the terminal directly, but many implementation of C feature a special input function that does the same thing, getpass().

The getpass() function is defined in the unistd.h header file. Here is its man page format:

char *getpass(const char *prompt);

The sole argument is a prompt string, sent to standard output. The function accepts input — with local echo off — and returns a pointer to the text input. Unlike the fgets() function, getpass() strips input of the newline character. Local echo is restored after the function call.

The maximum size of the input string varies. It may be represented by a constant value, such as _PASSWORD_LEN, which is defined in OS X in the pwd.h header file. Otherwise, most implementations set the string size to 128 characters.

Here’s sample code:

#include <stdio.h>
#include <unistd.h>

int main()
{
    char *password;

    /* fetch the password */
    password = getpass("Your password: ");
    printf("Your password is '%s'\n",password);

    return(0);
}

The getpass() function disables local echo and outputs the prompt. Input text is referenced by the password char pointer, then output in the printf() statement:

Your password:
Your password is 'this is a test'

Don’t fret if your compiler’s C library lacks the getpass() function. Many Windows compilers, such as the MinGW compiler used with Code::Blocks, lack this function. The Linux shell apps for Windows 10 do sport getpass(). Further, for any Linux/Unix system, you can program the terminal directly to suppress local echo and craft your own password input function. I cover this process in next week’s Lesson.

Leave a Reply