Tata2
Tata2

Reputation: 933

scanf() without displaying on screen

Is there any function in C on Linux that permit to wait an user input without displaying on terminal what he is typing ? (like when you enter your password on terminal on Linux)

I found getch() but it's not working on Linux ... :(

I found this but it's too complicated ... :

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

int     main(void)
{
   char buffer[100];
   struct termios infos;
   int   size;

   if (tcgetattr(STDIN_FILENO, &infos) == -1)                                                                                                  
   {
        fprintf(stderr, "Erreur tcgetattr.\n");
        return (EXIT_FAILURE);
   }
   infos.c_lflag &= ~ECHO;                                                                                                                                 

   if (tcsetattr(STDIN_FILENO, TCSANOW, &infos) == -1)                                                                                        
   {
        fprintf(stderr, "Erreur tcsetattr.\n");
        return (EXIT_FAILURE);
   }
   if ((size = read(STDIN_FILENO, buffer, sizeof(char) * 100)) == -1)                                            
   {
        fprintf(stderr, "Erreur durant la lecture.\n");
        return (EXIT_FAILURE);
   }
   buffer[size - 1] = '\0';
   printf("le buffer contient [%s]\n", buffer);                                                                                                 
   return (EXIT_SUCCESS);
}

Upvotes: 1

Views: 5059

Answers (2)

zwol
zwol

Reputation: 140786

The getpass function is not reliably present and has "obsolete, avoid" warnings in its manpage; however, it does essentially what you want. (I suspect it was obsoleted because it's not reentrant and doesn't allow the entry of an arbitrarily long password, which is kind of important nowadays.) The readpassphrase function is even less portable and has its own quirks (most of the flags should not be used, for instance) but does let you control how big the read buffer is. And gnulib has getpass-gnu, which adheres to the getpass calling convention but returns a malloced string rather than a pointer to static storage, thus fixing the major problems with the original getpass.

In a serious program I would probably start with the gnulib getpass, rename the function (to avoid potential conflicts with libc) and then hack out some of the more dubious features (like reading from stdin if /dev/tty is unavailable - the Right Thing there is to fail hard, but provide some other way of getting a passphrase into the program for scripting use). Or, if feasible, I would build the program around SSH keys rather than passwords.

Upvotes: 1

abligh
abligh

Reputation: 25169

It's not scanf that is displaying the characters on screen, it's the terminal emulation which is echoing characters you type. You can disable that using the technique you suggested (or use a library to hide this), but no amount of fiddling with other functions to read STDIN is going to help.

Upvotes: 3

Related Questions