paulo1205
(usa Ubuntu)
Enviado em 29/09/2014 - 10:20h
Não dá para fazer com C puro, pois a linguagem padronizada procura propositalmente não ter vínculos com dispositivos físicos específicos, como um terminal ou um teclado. Para conseguir o que você quer, tem de entrar em especificidades do seu hardware e sistema operacional.
Um colega mencionou, acima, a função
getpass(). O problema é que ela foi removida do padrão SUS (de
Single Unix Specification) e do POSIX. No Linux, ela está marcada como obsoleta e com indicação clara na documentação de que não deve mais ser usada.
Não sei o porquê dessa obsolescência, mas tenho o palpite de que a não reentrância e algumas amarrações de tamanho máximo que passaram a não fazer muito sentido com mecanismos de autenticação mais novos devem ter pesado na decisão.
A alternativa que resta é fazer exatamente o que essa função fazia, mas manualmente. A saber:
0) Estudar profundamente a documentação de
termios (“man 4 termios”).
1) Abrir (com
open(), não com
fopen()!) "/dev/tty" para leitura e escrita. Essa operação pode falhar se o programa for rodado sem um terminal associado (por exemplo: a partir do cron ou numa sessão de SSH que não tenha alocado um pseudo-terminal).
2) Com descritor recebido em (1), chamar
tcgetattr() para salvar a configuração atual do terminal.
3) Ainda sobre o mesmo descritor, usar
tcsetattr() para desligar o modo canônico do terminal e o eco de caracteres digitados, e possivelmente definir entrada caráter a caráter e sem
timeout.
4) Fazer um
loop com
read() sobre o descritor recebido em (1) para ler caráter por caráter, testando sempre se ocorreu fim de arquivo (i.e. o terminal foi fechado) ou se o usuário teclou
Enter. Se se desejar, imprimir um asterisco após ler cada caráter válido da senha.
5) Restaurar a configuração original do terminal.
6) Fechar o descritor recebido em (1).