Understanding Unix/Linux Programming-用户程序play_again4.c
1 /* play_again4.c 2 * When no is input , restore the tty settings 3 */ 4 5 #include <stdio.h> 6 #include <termios.h> 7 #include <fcntl.h> 8 #include <string.h> 9 #include <signal.h> 10 #include <stdlib.h> 11 12 #define ASK "Do you want to play again?" 13 #define TRIES 3 14 #define SLEEPTIME 2 15 #define BEEP putchar('\a'); 16 17 void ctrl_c_handler(int); 18 int get_response(char * , int ); 19 int get_ok_char(void); 20 void set_nodelay_mode(void); 21 void set_cr_noecho_mode(void); 22 void tty_mode(int); 23 24 int main() 25 { 26 int response ; 27 tty_mode(0); 28 set_cr_noecho_mode(); 29 set_nodelay_mode(); 30 31 signal(SIGINT , ctrl_c_handler) ; // Set signal responding function 32 signal(SIGQUIT , SIG_IGN ); 33 34 response = get_response(ASK , TRIES ); 35 36 tty_mode(1); 37 return response ; 38 } 39 40 void ctrl_c_handler(int signum ) 41 { 42 tty_mode(1) ; // Restore the tty settings 43 exit(1) ; 44 } 45 46 int get_response(char * qiz , int tries ) 47 { 48 int input ; 49 int maxtries = tries ; 50 printf("%s(y/n)" , qiz); 51 fflush(stdout); 52 while(1) 53 { 54 BEEP ; 55 sleep(SLEEPTIME); 56 input = tolower(get_ok_char()) ; 57 if(input == 'y') 58 { 59 printf("\n"); 60 return 0 ; 61 } 62 if(input == 'n') 63 { 64 printf("\n"); 65 return 1 ; 66 } 67 if(maxtries -- <= 0 ) 68 { 69 printf("\n"); 70 return 2 ; 71 } 72 BEEP ; 73 } 74 } 75 76 int get_ok_char(void) 77 { 78 int c ; 79 while( (c = getchar() ) != EOF && strchr("yYnN" , c ) == NULL ) 80 ; 81 return c ; 82 } 83 84 void set_cr_noecho_mode(void) 85 { 86 struct termios ttystate ; 87 tcgetattr(0 , &ttystate); 88 ttystate.c_lflag &= ~ICANON ; // No Buffering 89 ttystate.c_lflag &= ~ECHO ; 90 ttystate.c_cc[VMIN] = 1 ; //Get one char one time 91 tcsetattr( 0 , TCSANOW , &ttystate); 92 } 93 94 void set_nodelay_mode(void) 95 { 96 int termflags ; 97 termflags = fcntl(0 , F_GETFL); 98 termflags |= O_NDELAY ; 99 fcntl(0 , F_SETFL , termflags) ; 100 } 101 102 void tty_mode(int mode) 103 { 104 static struct termios original_mode ;// 设置静态结构体变量 105 if(mode == 0 ) 106 { 107 tcgetattr( 0 , & original_mode);// 存储原有设置 108 } 109 else 110 { 111 //还原原有设置 112 if( tcsetattr(0 , TCSANOW , & original_mode) == -1 ) 113 { 114 perror("Restore tty settings failed!\n"); 115 } 116 } 117 }