Even though this is a very old question that has already been answered, here's what I've been using (which is very similar to the accepted answer):
#include <termios.h>
#include <cstdio>
//
// The following is a slightly modifed version taken from:
// http://www.gnu.org/software/libc/manual/html_node/getpass.html
//
ssize_t my_getpass (char *prompt, char **lineptr, size_t *n, FILE *stream)
{
struct termios _old, _new;
int nread;
/* Turn echoing off and fail if we can’t. */
if (tcgetattr (fileno (stream), &_old) != 0)
return -1;
_new = _old;
_new.c_lflag &= ~ECHO;
if (tcsetattr (fileno (stream), TCSAFLUSH, &_new) != 0)
return -1;
/* Display the prompt */
if (prompt)
printf("%s", prompt);
/* Read the password. */
nread = getline (lineptr, n, stream);
/* Remove the carriage return */
if (nread >= 1 && (*lineptr)[nread - 1] == '\n')
{
(*lineptr)[nread-1] = 0;
nread--;
}
printf("\n");
/* Restore terminal. */
(void) tcsetattr (fileno (stream), TCSAFLUSH, &_old);
return nread;
}
//
// Test harness - demonstrate calling my_getpass().
//
int main(int argc, char *argv[])
{
size_t maxlen = 255;
char pwd[maxlen];
char *pPwd = pwd; // <-- haven't figured out how to avoid this.
int count = my_getpass((char*)"Enter Password: ", &pPwd, &maxlen, stdin);
printf("Size of password: %d\nPassword in plaintext: %s\n", count, pwd);
return 0;
}
getpass()
obsolete and even removed from POSIX, without providing an alternative (like NetBSD'sgetpass_r()
). Now everyone makes his/her own version, ridden with security/usability/portability bugs. – Fecund