tags:

views:

674

answers:

4

I could use getpass() to get a password. However, the man page says:

This function is obsolete. Do not use it.

What is the current way to get a password from the user's terminal without echoing it, in a POSIX-compliant way? [Originally I said "portably", but my intention was to avoid using an obsolete function.]

+4  A: 

You could use the ncurses library to read from standard input without echoing the results to the screen. (Call noecho() before getting any input). The library has been around for ages and works on a wide variety of platforms (the windows version can be found here)

indy
I made a simple curses app (it's been a couple decaded since I used curses), and found that it cleared the screen when I did initscr(). There is probably some way around that, but it wasn't obvious from a quick perusal of the man pages.
Jerry Penner
+1  A: 

On windows, you can probably use the SetConsoleMode api, described here.

Brian
+2  A: 

According to the University of Milwaukee's documentation it is obsolete because:

The getpass() function is not threadsafe because it manipulates global signal state.

The getpass() function is scheduled to be withdrawn from a future version of the X/Open CAE Specification.

Lucas McCoy
+3  A: 

this should work on linux/macosx, a windows version should use Get/Set ConsoleMode

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>

int
main(int argc, char **argv)
{
    struct termios oflags, nflags;
    char password[64];

    /* disabling echo */
    tcgetattr(fileno(stdin), &oflags);
    nflags = oflags;
    nflags.c_lflag &= ~ECHO;
    nflags.c_lflag |= ECHONL;

    if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) {
        perror("tcsetattr");
        return EXIT_FAILURE;
    }

    printf("password: ");
    fgets(password, sizeof(password), stdin);
    password[strlen(password) - 1] = 0;
    printf("you typed '%s'\n", password);

    /* restore terminal */
    if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
        perror("tcsetattr");
        return EXIT_FAILURE;
    }

    return 0;
}
dfa
This seems the most straightforward way to me.
Jerry Penner