1

I am interested in gathering a password from a user.

When the user is prompted for their password, I want to echo back to them * (asterisks) for each character they input.

void changeEcho() {
    termios term;
    tcgetattr(STDIN_FILENO, &term);
    term.c_lflag &= ~ECHO;
    tcsetattr(STDIN_FILENO, TCSANOW, &term);
}

I know that this will turn the echo off, but I am interested in echoing something that I choose, in my case '*'.

Nick
  • 25
  • 8
  • 3
    That is not a form of echo. Programs do that by simply writing `*` in response to every character they read without echo. – that other guy May 01 '19 at 01:54
  • I am not sure I understand what you mean. When I have the flashing cursor, and I type "password", I want to see "********" in the terminal. One * each time I press a key. – Nick May 01 '19 at 02:01

1 Answers1

3

The feature you describe is unrelated to echo. Instead, you implement it yourself by simply reading a character and writing a * in a loop:

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


int main() {
    char c;
    char p = '*';
    struct termios term, original;
    tcgetattr(STDIN_FILENO, &term);
    original = term;
    term.c_lflag &= ~ECHO & ~ICANON;
    tcsetattr(STDIN_FILENO, TCSANOW, &term);

    while (read(STDIN_FILENO, &c, 1) == 1 && c != '\n')
        write(STDOUT_FILENO, &p, 1);
    printf("\n");

    tcsetattr(STDIN_FILENO, TCSANOW, &original);
    return 0;
}

When you run it and type things, all you see are *s:

$ gcc foo.c && ./foo
***********

It's up to the program to store the string, handle backspace, and only show a single * per multibyte character.

that other guy
  • 116,971
  • 11
  • 170
  • 194
  • exactly what I was looking for. thank you. I only thought it had to do with ECHO because that is what was handling the output to the screen. – Nick May 01 '19 at 03:34