选择java 进入自由开放的国度

随笔 - 49, 文章 - 3, 评论 - 154, 引用 - 1
数据加载中……

linux终端控制和信号初步

讲解了终端的基本控制方法,通过五个例子一步一步完善,最终形成了完善的终端控制例程.

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 后必须回车才能使程序接收输入
      -输入非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 

缺陷:每次给出提示,不友好,可以不显示用户输入

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 
缺陷:当用户什么都没有输入时,程序还在运行

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-- == 0return 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中止程序,系统不能恢复到原来的状态
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-- == 0return 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 

posted on 2006-04-02 11:52 soochow_hhb 以java论成败 以架构论英雄 阅读(778) 评论(1)  编辑  收藏 所属分类: Reading

评论

# re: linux终端控制和信号初步  回复  更多评论   

很好的例子...
有空要深究一下.
2006-06-30 09:39 | 流浪人

只有注册用户登录后才能发表评论。


网站导航: