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 }