8

Suppose I'm reading a string using fgets, and I want to prevent that string's characters from echoing in the terminal internally (no bash tricks). How can I do that?

zengod
  • 1,114
  • 13
  • 26

1 Answers1

12

Assuming you're running on a POSIX-compatible OS, you need to play with local control terminal (termios) flags for stdin using tcgetattr() and tcsetattr():

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

int main(int argc, char *argv[])
{
    printf("Enter password: ");

    struct termios term;
    tcgetattr(fileno(stdin), &term);

    term.c_lflag &= ~ECHO;
    tcsetattr(fileno(stdin), 0, &term);

    char passwd[32];
    fgets(passwd, sizeof(passwd), stdin);

    term.c_lflag |= ECHO;
    tcsetattr(fileno(stdin), 0, &term);

    printf("\nYour password is: %s\n", passwd);
}

You might want to disable additional flags during input. This is just an example. Beware of interrupts — you really want to reset the terminal state even if your program is interrupted.

Also this might probably not work for all tty types.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Alex Skalozub
  • 2,511
  • 16
  • 15
  • It will work on systems that conform with at least POSIX.1-2001. That eliminates DOS/Windows. (unless you run under WSL -- no native 64-bit POSIX support in the windows desktop) – David C. Rankin Jan 26 '20 at 22:18
  • @DavidC.Rankin sure, I've added a clarification. But since the author was referring bash, I assumed DOS/Windows is out of scope. – Alex Skalozub Jan 26 '20 at 22:21
  • 2
    That covers it, `fgetc` allows a mask character as well, see [Hide password input on terminal](https://stackoverflow.com/questions/6856635/hide-password-input-on-terminal/32421674#32421674) – David C. Rankin Jan 26 '20 at 22:24