linux终端控制和信号初步
讲解了终端的基本控制方法,通过五个例子一步一步完善,最终形成了完善的终端控制例程.
1.play_again0.c
功能:读入用户输入,输入y 返回0,输入n 返回1
-输入非y 和n 的字符程序没有提示和处理
2, play_again1.c
功能:立即响应用户输入输入不合法,给出提示信息.
缺陷:每次给出提示,不友好,可以不显示用户输入
3,play_again2.c
功能:对于输入的字符不显示,当输入合法字符时正确返回
4.play_again3.c
功能:用户不输入时,程序超时退出
5.play_again4.c
功能:加入了信号处理
1.play_again0.c
功能:读入用户输入,输入y 返回0,输入n 返回1
1
#include
<
stdio.h
>
2 #include < termios.h >
3
4 #define QUESTION " Do you want another transaction "
5
6 int get_response( char * );
7
8 int main()
9 {
10 int response;
11 response = get_response(QUESTION);
12 if (response == 0 )
13 printf( " the char you put is y\n " );
14 else
15 printf( " the char you put is n\n " );
16
17 return response;
18
19 }
20
21 int get_response( char * question)
22 {
23 printf( " %s (y/n)? " , question);
24 while ( 1 )
25 {
26 switch (getchar())
27 {
28 case ' y ' :
29 case ' Y ' : return 0 ;
30 case ' n ' :
31 case ' N ' :
32 case EOF: return 1 ;
33
34 }
35 }
36 }
37
缺陷: -用户输入y 和n 后必须回车才能使程序接收输入
2 #include < termios.h >
3
4 #define QUESTION " Do you want another transaction "
5
6 int get_response( char * );
7
8 int main()
9 {
10 int response;
11 response = get_response(QUESTION);
12 if (response == 0 )
13 printf( " the char you put is y\n " );
14 else
15 printf( " the char you put is n\n " );
16
17 return response;
18
19 }
20
21 int get_response( char * question)
22 {
23 printf( " %s (y/n)? " , question);
24 while ( 1 )
25 {
26 switch (getchar())
27 {
28 case ' y ' :
29 case ' Y ' : return 0 ;
30 case ' n ' :
31 case ' N ' :
32 case EOF: return 1 ;
33
34 }
35 }
36 }
37
-输入非y 和n 的字符程序没有提示和处理
2, play_again1.c
功能:立即响应用户输入输入不合法,给出提示信息.
1
/*
2 * set tty into char -by char mode, read char, return result
3 * response the input immediately
4 */
5 #include < stdio.h >
6 #include < termios.h >
7
8 #define QUESTION " Do you want another transaction "
9
10 int get_response( char * );
11 void tty_mode( int );
12 void set_crmode();
13
14 int main()
15 {
16 int response;
17 tty_mode( 0 );
18 set_crmode();
19 response = get_response(QUESTION);
20 if (response == 0 )
21 printf( " \n the char you put is y\n " );
22 else
23 printf( " \n the char you put is n\n " );
24
25 tty_mode( 1 );
26 return response;
27
28 }
29
30 int get_response( char * question)
31 {
32 printf( " %s (y/n)? " , question);
33 while ( 1 )
34 {
35 switch ( char input = getchar())
36 {
37 case ' y ' :
38 case ' Y ' : return 0 ;
39 case ' n ' :
40 case ' N ' :
41 case EOF: return 1 ;
42 default :
43 printf( " \n cannot understatnd %c, " , input);
44 printf( " please type y or n \n " );
45
46 }
47 }
48 }
49
50 void set_crmode()
51 /*
52 * put file descriptor 9 into char -by -char mode
53 * in common mode ,you can input 'stty -icanon' .
54 */
55 {
56 struct termios ttystate;
57 tcgetattr( 0 , & ttystate);
58 ttystate.c_lflag &= ~ ICANON;
59 ttystate.c_cc[VMIN] = 1 ; // get 1 char at a time
60 tcsetattr( 0 , TCSANOW, & ttystate);
61 }
62
63 void tty_mode( int how)
64 {
65 static struct termios original_mode;
66 if (how == 0 )
67 tcgetattr( 0 , & original_mode);
68 else
69 tcsetattr( 0 , TCSANOW, & original_mode);
70
71 }
72
2 * set tty into char -by char mode, read char, return result
3 * response the input immediately
4 */
5 #include < stdio.h >
6 #include < termios.h >
7
8 #define QUESTION " Do you want another transaction "
9
10 int get_response( char * );
11 void tty_mode( int );
12 void set_crmode();
13
14 int main()
15 {
16 int response;
17 tty_mode( 0 );
18 set_crmode();
19 response = get_response(QUESTION);
20 if (response == 0 )
21 printf( " \n the char you put is y\n " );
22 else
23 printf( " \n the char you put is n\n " );
24
25 tty_mode( 1 );
26 return response;
27
28 }
29
30 int get_response( char * question)
31 {
32 printf( " %s (y/n)? " , question);
33 while ( 1 )
34 {
35 switch ( char input = getchar())
36 {
37 case ' y ' :
38 case ' Y ' : return 0 ;
39 case ' n ' :
40 case ' N ' :
41 case EOF: return 1 ;
42 default :
43 printf( " \n cannot understatnd %c, " , input);
44 printf( " please type y or n \n " );
45
46 }
47 }
48 }
49
50 void set_crmode()
51 /*
52 * put file descriptor 9 into char -by -char mode
53 * in common mode ,you can input 'stty -icanon' .
54 */
55 {
56 struct termios ttystate;
57 tcgetattr( 0 , & ttystate);
58 ttystate.c_lflag &= ~ ICANON;
59 ttystate.c_cc[VMIN] = 1 ; // get 1 char at a time
60 tcsetattr( 0 , TCSANOW, & ttystate);
61 }
62
63 void tty_mode( int how)
64 {
65 static struct termios original_mode;
66 if (how == 0 )
67 tcgetattr( 0 , & original_mode);
68 else
69 tcsetattr( 0 , TCSANOW, & original_mode);
70
71 }
72
缺陷:每次给出提示,不友好,可以不显示用户输入
3,play_again2.c
功能:对于输入的字符不显示,当输入合法字符时正确返回
1
/*
2 * set tty into char -by char mode, read char, return result
3 * response the input immediately
4 * ingore non-y or non-n char
5 * todo: timeout if user walks away
6 */
7 #include < stdio.h >
8 #include < termios.h >
9
10 #define QUESTION " Do you want another transaction "
11
12 int get_response( char * );
13 void tty_mode( int );
14 void set_crmode();
15
16 int main()
17 {
18 int response;
19 tty_mode( 0 );
20 set_crmode();
21 response = get_response(QUESTION);
22 if (response == 0 )
23 printf( " \n the char you put is y\n " );
24 else
25 printf( " \n the char you put is n\n " );
26
27 tty_mode( 1 );
28 return response;
29
30 }
31
32 int get_response( char * question)
33 {
34 char input;
35 printf( " %s (y/n)? " , question);
36 while ( 1 )
37 {
38 switch (input = getchar())
39 {
40 case ' y ' :
41 case ' Y ' : return 0 ;
42 case ' n ' :
43 case ' N ' :
44 case EOF: return 1 ;
45 // default:
46 // printf("\n cannot understatnd %c,", input);
47 // printf("please type y or n \n");
48
49 }
50 }
51 }
52
53 void set_crmode()
54 /*
55 * put file descriptor 9 into char -by -char mode
56 * in common mode ,you can input 'stty -icanon' .
57 */
58 {
59 struct termios ttystate;
60 tcgetattr( 0 , & ttystate);
61 ttystate.c_lflag &= ~ ICANON; // no buffering
62 ttystate.c_lflag &= ~ ECHO; // no echo either
63 ttystate.c_cc[VMIN] = 1 ; // get 1 char at a time
64 tcsetattr( 0 , TCSANOW, & ttystate); // install settings
65 }
66
67 void tty_mode( int how)
68 {
69 static struct termios original_mode;
70 if (how == 0 )
71 tcgetattr( 0 , & original_mode);
72 else
73 tcsetattr( 0 , TCSANOW, & original_mode);
74
75 }
76
缺陷:当用户什么都没有输入时,程序还在运行
2 * set tty into char -by char mode, read char, return result
3 * response the input immediately
4 * ingore non-y or non-n char
5 * todo: timeout if user walks away
6 */
7 #include < stdio.h >
8 #include < termios.h >
9
10 #define QUESTION " Do you want another transaction "
11
12 int get_response( char * );
13 void tty_mode( int );
14 void set_crmode();
15
16 int main()
17 {
18 int response;
19 tty_mode( 0 );
20 set_crmode();
21 response = get_response(QUESTION);
22 if (response == 0 )
23 printf( " \n the char you put is y\n " );
24 else
25 printf( " \n the char you put is n\n " );
26
27 tty_mode( 1 );
28 return response;
29
30 }
31
32 int get_response( char * question)
33 {
34 char input;
35 printf( " %s (y/n)? " , question);
36 while ( 1 )
37 {
38 switch (input = getchar())
39 {
40 case ' y ' :
41 case ' Y ' : return 0 ;
42 case ' n ' :
43 case ' N ' :
44 case EOF: return 1 ;
45 // default:
46 // printf("\n cannot understatnd %c,", input);
47 // printf("please type y or n \n");
48
49 }
50 }
51 }
52
53 void set_crmode()
54 /*
55 * put file descriptor 9 into char -by -char mode
56 * in common mode ,you can input 'stty -icanon' .
57 */
58 {
59 struct termios ttystate;
60 tcgetattr( 0 , & ttystate);
61 ttystate.c_lflag &= ~ ICANON; // no buffering
62 ttystate.c_lflag &= ~ ECHO; // no echo either
63 ttystate.c_cc[VMIN] = 1 ; // get 1 char at a time
64 tcsetattr( 0 , TCSANOW, & ttystate); // install settings
65 }
66
67 void tty_mode( int how)
68 {
69 static struct termios original_mode;
70 if (how == 0 )
71 tcgetattr( 0 , & original_mode);
72 else
73 tcsetattr( 0 , TCSANOW, & original_mode);
74
75 }
76
4.play_again3.c
功能:用户不输入时,程序超时退出
1
/*
2 * set tty into char -by char mode, read char, return result
3 * response the input immediately
4 * ingore non-y or non-n char
5 * add timeout machemism
6 * todo: reset terminal mode on interrupt
7 */
8 #include < stdio.h >
9 #include < unistd.h >
10 #include < termios.h >
11 #include < fcntl.h >
12 #include < string.h >
13
14
15 #define QUESTION " Do you want another transaction "
16 #define TRIES 3
17 #define SLEEPTIME 2
18 #define BEEP putchar( ' \a ' )
19
20 int get_response( char * );
21 void tty_mode( int );
22 void set_crmode();
23 void set_nodelay_mode(); // timeout set
24
25 int main()
26 {
27 BEEP;
28
29 int response, maxtries;
30 maxtries = TRIES;
31 tty_mode( 0 );
32 set_crmode();
33 set_nodelay_mode();
34 response = get_response(QUESTION);
35 if (response == 0 )
36 printf( " \n the char you put is y\n " );
37 else if (response == 1 )
38 printf( " \n the char you put is n\n " );
39 else if (response == 2 )
40 printf( " \n timeout\n " );
41
42 tty_mode( 1 );
43 return response;
44
45 }
46
47 char get_ok_char()
48 {
49 int c;
50 while ( (c = getchar()) != EOF && strchr( " yYNn " , c) == NULL);
51 return c;
52 }
53 int get_response( char * question)
54 {
55 char input;
56 int maxtries = TRIES;
57 printf( " %s (y/n)? " , question);
58 fflush(stdout);
59 while ( 1 )
60 {
61 sleep(SLEEPTIME);
62 // input = tolower(get_ok_char());
63 input = get_ok_char();
64 if (input == ' y ' ) return 0 ;
65 if (input == ' n ' ) return 1 ;
66 if (maxtries -- == 0 ) return 2 ;
67
68 BEEP;
69
70 }
71 }
72
73 void set_crmode()
74 /*
75 * put file descriptor 9 into char -by -char mode
76 * in common mode ,you can input 'stty -icanon' .
77 */
78 {
79 struct termios ttystate;
80 tcgetattr( 0 , & ttystate);
81 ttystate.c_lflag &= ~ ICANON; // no buffering
82 ttystate.c_lflag &= ~ ECHO; // no echo either
83 ttystate.c_cc[VMIN] = 1 ; // get 1 char at a time
84 tcsetattr( 0 , TCSANOW, & ttystate); // install settings
85 }
86
87 void tty_mode( int how)
88 {
89 static struct termios original_mode;
90 static int original_flags;
91 if (how == 0 ){
92 tcgetattr( 0 , & original_mode);
93 original_flags = fcntl( 0 , F_GETFL);
94 }
95 else
96 {
97 tcsetattr( 0 , TCSANOW, & original_mode);
98 fcntl( 0 , F_SETFL, original_flags);
99 }
100
101 }
102
103 void set_nodelay_mode()
104 /*
105 * put file descriptor 9 into no-0delay mode
106 * use fcntl to set bits
107 * notes: tcsetattr() will do something similar, but it is complicated
108 */
109 {
110 int termflags;
111 termflags = fcntl( 0 , F_GETFL); // read curr. settings
112 termflags |= O_NDELAY;
113 fcntl( 0 , F_SETFL, termflags);
114 }
115
缺陷:如果用户通过ctrl-c中止程序,系统不能恢复到原来的状态
2 * set tty into char -by char mode, read char, return result
3 * response the input immediately
4 * ingore non-y or non-n char
5 * add timeout machemism
6 * todo: reset terminal mode on interrupt
7 */
8 #include < stdio.h >
9 #include < unistd.h >
10 #include < termios.h >
11 #include < fcntl.h >
12 #include < string.h >
13
14
15 #define QUESTION " Do you want another transaction "
16 #define TRIES 3
17 #define SLEEPTIME 2
18 #define BEEP putchar( ' \a ' )
19
20 int get_response( char * );
21 void tty_mode( int );
22 void set_crmode();
23 void set_nodelay_mode(); // timeout set
24
25 int main()
26 {
27 BEEP;
28
29 int response, maxtries;
30 maxtries = TRIES;
31 tty_mode( 0 );
32 set_crmode();
33 set_nodelay_mode();
34 response = get_response(QUESTION);
35 if (response == 0 )
36 printf( " \n the char you put is y\n " );
37 else if (response == 1 )
38 printf( " \n the char you put is n\n " );
39 else if (response == 2 )
40 printf( " \n timeout\n " );
41
42 tty_mode( 1 );
43 return response;
44
45 }
46
47 char get_ok_char()
48 {
49 int c;
50 while ( (c = getchar()) != EOF && strchr( " yYNn " , c) == NULL);
51 return c;
52 }
53 int get_response( char * question)
54 {
55 char input;
56 int maxtries = TRIES;
57 printf( " %s (y/n)? " , question);
58 fflush(stdout);
59 while ( 1 )
60 {
61 sleep(SLEEPTIME);
62 // input = tolower(get_ok_char());
63 input = get_ok_char();
64 if (input == ' y ' ) return 0 ;
65 if (input == ' n ' ) return 1 ;
66 if (maxtries -- == 0 ) return 2 ;
67
68 BEEP;
69
70 }
71 }
72
73 void set_crmode()
74 /*
75 * put file descriptor 9 into char -by -char mode
76 * in common mode ,you can input 'stty -icanon' .
77 */
78 {
79 struct termios ttystate;
80 tcgetattr( 0 , & ttystate);
81 ttystate.c_lflag &= ~ ICANON; // no buffering
82 ttystate.c_lflag &= ~ ECHO; // no echo either
83 ttystate.c_cc[VMIN] = 1 ; // get 1 char at a time
84 tcsetattr( 0 , TCSANOW, & ttystate); // install settings
85 }
86
87 void tty_mode( int how)
88 {
89 static struct termios original_mode;
90 static int original_flags;
91 if (how == 0 ){
92 tcgetattr( 0 , & original_mode);
93 original_flags = fcntl( 0 , F_GETFL);
94 }
95 else
96 {
97 tcsetattr( 0 , TCSANOW, & original_mode);
98 fcntl( 0 , F_SETFL, original_flags);
99 }
100
101 }
102
103 void set_nodelay_mode()
104 /*
105 * put file descriptor 9 into no-0delay mode
106 * use fcntl to set bits
107 * notes: tcsetattr() will do something similar, but it is complicated
108 */
109 {
110 int termflags;
111 termflags = fcntl( 0 , F_GETFL); // read curr. settings
112 termflags |= O_NDELAY;
113 fcntl( 0 , F_SETFL, termflags);
114 }
115
5.play_again4.c
功能:加入了信号处理
1
/*
2 * set tty into char -by char mode, read char, return result
3 * response the input immediately
4 * ingore non-y or non-n char
5 * add timeout machemism
6 * add reset terminal mode on interrupt
7 * ignore ctrl-C signal
8 */
9 #include < stdio.h >
10 #include < unistd.h >
11 #include < termios.h >
12 #include < fcntl.h >
13 #include < string.h >
14 #include < signal.h >
15
16 #define QUESTION " Do you want another transaction "
17 #define TRIES 3
18 #define SLEEPTIME 2
19 #define BEEP putchar( ' \a ' )
20
21 int get_response( char * );
22 void tty_mode( int );
23 void set_crmode();
24 void set_nodelay_mode(); // timeout set
25 void ctrl_c_handler( int signum);
26
27 int main()
28 {
29 BEEP;
30
31 int response, maxtries;
32 maxtries = TRIES;
33 tty_mode( 0 );
34 set_crmode();
35 set_nodelay_mode();
36 signal(SIGINT, ctrl_c_handler);
37 signal(SIGQUIT, SIG_IGN);
38 response = get_response(QUESTION);
39 if (response == 0 )
40 printf( " \n the char you put is y\n " );
41 else if (response == 1 )
42 printf( " \n the char you put is n\n " );
43 else if (response == 2 )
44 printf( " \n timeout\n " );
45
46 tty_mode( 1 );
47 return response;
48
49 }
50
51 char get_ok_char()
52 {
53 int c;
54 while ( (c = getchar()) != EOF && strchr( " yYNn " , c) == NULL);
55 return c;
56 }
57 int get_response( char * question)
58 {
59 char input;
60 int maxtries = TRIES;
61 printf( " %s (y/n)? " , question);
62 fflush(stdout);
63 while ( 1 )
64 {
65 sleep(SLEEPTIME);
66 // input = tolower(get_ok_char());
67 input = get_ok_char();
68 if (input == ' y ' ) return 0 ;
69 if (input == ' n ' ) return 1 ;
70 if (maxtries -- == 0 ) return 2 ;
71
72 BEEP;
73
74 }
75 }
76
77 void set_crmode()
78 /*
79 * put file descriptor 9 into char -by -char mode
80 * in common mode ,you can input 'stty -icanon' .
81 */
82 {
83 struct termios ttystate;
84 tcgetattr( 0 , & ttystate);
85 ttystate.c_lflag &= ~ ICANON; // no buffering
86 ttystate.c_lflag &= ~ ECHO; // no echo either
87 ttystate.c_cc[VMIN] = 1 ; // get 1 char at a time
88 tcsetattr( 0 , TCSANOW, & ttystate); // install settings
89 }
90
91 void tty_mode( int how)
92 {
93 static struct termios original_mode;
94 static int original_flags;
95 if (how == 0 ){
96 tcgetattr( 0 , & original_mode);
97 original_flags = fcntl( 0 , F_GETFL);
98 }
99 else
100 {
101 tcsetattr( 0 , TCSANOW, & original_mode);
102 fcntl( 0 , F_SETFL, original_flags);
103 }
104
105 }
106
107 void set_nodelay_mode()
108 /*
109 * put file descriptor 9 into no-0delay mode
110 * use fcntl to set bits
111 * notes: tcsetattr() will do something similar, but it is complicated
112 */
113 {
114 int termflags;
115 termflags = fcntl( 0 , F_GETFL); // read curr. settings
116 termflags |= O_NDELAY;
117 fcntl( 0 , F_SETFL, termflags);
118 }
119 void ctrl_c_handler( int signum)
120 {
121 // called if SIGINT is detected and reset tty and scram
122 tty_mode( 1 );
123 exit( 1 );
124 }
125
2 * set tty into char -by char mode, read char, return result
3 * response the input immediately
4 * ingore non-y or non-n char
5 * add timeout machemism
6 * add reset terminal mode on interrupt
7 * ignore ctrl-C signal
8 */
9 #include < stdio.h >
10 #include < unistd.h >
11 #include < termios.h >
12 #include < fcntl.h >
13 #include < string.h >
14 #include < signal.h >
15
16 #define QUESTION " Do you want another transaction "
17 #define TRIES 3
18 #define SLEEPTIME 2
19 #define BEEP putchar( ' \a ' )
20
21 int get_response( char * );
22 void tty_mode( int );
23 void set_crmode();
24 void set_nodelay_mode(); // timeout set
25 void ctrl_c_handler( int signum);
26
27 int main()
28 {
29 BEEP;
30
31 int response, maxtries;
32 maxtries = TRIES;
33 tty_mode( 0 );
34 set_crmode();
35 set_nodelay_mode();
36 signal(SIGINT, ctrl_c_handler);
37 signal(SIGQUIT, SIG_IGN);
38 response = get_response(QUESTION);
39 if (response == 0 )
40 printf( " \n the char you put is y\n " );
41 else if (response == 1 )
42 printf( " \n the char you put is n\n " );
43 else if (response == 2 )
44 printf( " \n timeout\n " );
45
46 tty_mode( 1 );
47 return response;
48
49 }
50
51 char get_ok_char()
52 {
53 int c;
54 while ( (c = getchar()) != EOF && strchr( " yYNn " , c) == NULL);
55 return c;
56 }
57 int get_response( char * question)
58 {
59 char input;
60 int maxtries = TRIES;
61 printf( " %s (y/n)? " , question);
62 fflush(stdout);
63 while ( 1 )
64 {
65 sleep(SLEEPTIME);
66 // input = tolower(get_ok_char());
67 input = get_ok_char();
68 if (input == ' y ' ) return 0 ;
69 if (input == ' n ' ) return 1 ;
70 if (maxtries -- == 0 ) return 2 ;
71
72 BEEP;
73
74 }
75 }
76
77 void set_crmode()
78 /*
79 * put file descriptor 9 into char -by -char mode
80 * in common mode ,you can input 'stty -icanon' .
81 */
82 {
83 struct termios ttystate;
84 tcgetattr( 0 , & ttystate);
85 ttystate.c_lflag &= ~ ICANON; // no buffering
86 ttystate.c_lflag &= ~ ECHO; // no echo either
87 ttystate.c_cc[VMIN] = 1 ; // get 1 char at a time
88 tcsetattr( 0 , TCSANOW, & ttystate); // install settings
89 }
90
91 void tty_mode( int how)
92 {
93 static struct termios original_mode;
94 static int original_flags;
95 if (how == 0 ){
96 tcgetattr( 0 , & original_mode);
97 original_flags = fcntl( 0 , F_GETFL);
98 }
99 else
100 {
101 tcsetattr( 0 , TCSANOW, & original_mode);
102 fcntl( 0 , F_SETFL, original_flags);
103 }
104
105 }
106
107 void set_nodelay_mode()
108 /*
109 * put file descriptor 9 into no-0delay mode
110 * use fcntl to set bits
111 * notes: tcsetattr() will do something similar, but it is complicated
112 */
113 {
114 int termflags;
115 termflags = fcntl( 0 , F_GETFL); // read curr. settings
116 termflags |= O_NDELAY;
117 fcntl( 0 , F_SETFL, termflags);
118 }
119 void ctrl_c_handler( int signum)
120 {
121 // called if SIGINT is detected and reset tty and scram
122 tty_mode( 1 );
123 exit( 1 );
124 }
125