dasman
dasman

Reputation: 311

linux terminal output

Hi I wrote a simple c prog to just accept a password while diplaying * to hide the input. But the * for the last character entered is not appearing at the right place. the code is below

int main(){  
int choice = 0;  
char pass[8];  
FILE *input;  
FILE *output;  
struct termios initial_settings, new_settings;  

if(!isatty(fileno(stdout))){  
    fprintf(stderr,"Not a terminal \n");  
}  
input = fopen("/dev/tty","r");  
output = fopen("/dev/tty","w");  
if(!input || !output){  
fprintf(stderr,"error opening");  
exit(1);  
}  
tcgetattr(fileno(input),&initial_settings);  
new_settings = initial_settings;  
new_settings.c_lflag &= ~ICANON;  
new_settings.c_lflag &= ~ECHO;  
new_settings.c_cc[VMIN] = 1;  
new_settings.c_cc[VTIME] = 0;  
new_settings.c_lflag &= ~ISIG;  
if(tcsetattr(fileno(input), TCSANOW, &new_settings) != 0) {  
fprintf(stderr,"could not set attributes\n");  
}

int count = 0;  
char ch;  
printf("Please enter the password: ");  
while (count<8){  
ch = fgetc(input);  

if(ch == '\n' || ch == '\r'){  
break;  
}else{  
fputc('*',stdout);  
pass[count] = ch;  
count++;  
}  
tcdrain(fileno(stdout));  
}  


fprintf(output,"you have entered :%s \n",pass);  
tcsetattr(fileno(input),TCSANOW,&initial_settings);  
exit(0);  
}  

The output is as follows:
Please enter the password:* * * * * * *
you have entered :12345678
* pasman@pasman-laptop:~$

Its an 8 character password & Notice that 7 *s appear as expected but the last * is appearing at the end of main.

Upvotes: 0

Views: 572

Answers (2)

Keith
Keith

Reputation: 43024

You're mixing stdio and another stream, output, talking directly to the tty. They have different buffers, and get flushed at different times. You really should just use one of them.

Upvotes: 1

Mitchell Currie
Mitchell Currie

Reputation: 2809

It's because you break before you write the last *: so add

fputc('*',stdout);

before

tcdrain(fileno(stdout)); 

Upvotes: 0

Related Questions