Unix-Linux编程实践教程——第六章
2017-10-21 13:56
459 查看
章节概要
本章节主要讲解终端控制以及信号,通过对终端输入过程的分析以及一个小游戏,让我们了解终端控制以及信号终端模式
规范模式:驱动程序输入的字符保存在缓冲区,并且仅在接受到回车键时才将缓冲的字符发送到程序。非规范模式:当缓冲和编辑功能被关闭时,连接被称为非规范模式。终端处理器仍旧进行特定字符处理,例如处理Ctrl-C以及换行符和回车符之间的转换。但是用于删除、单词删除和终止的编辑键没有特殊意义,被当做常规的数据输入。
raw模式:当所有处理都被关闭后,驱动程序将输入直接传递给程序,这种情况称为raw模式。
rotate.c
/****************************************************** > File Name: rotate.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月10日 星期二 11时35分22秒 ******************************************************/ #include<stdio.h> #include<ctype.h> int main(){ int c; while((c=getchar())!=EOF){ if(c=='z'){ c='a'; }else if(islower(c)){ c++; } putchar(c); } return 0; }
atm.sh
############################################################### # File Name: atm.sh # Author: Duke-wei # mail: 13540639584@163.com # Created Time: 2017年10月10日 星期二 12时43分36秒 ############################################################### #!/bin/bash while true do ./do_a_transaction if ./play_again then continue fi break done
do_a_transaction.c
/********************************************************* > File Name: do_a_transaction.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月10日 星期二 12时49分31秒 **********************************************************/ #include<stdio.h> int main(){ printf("OK,Got 100 Million\n"); return 0; }
play_again0.c
/********************************************************* > File Name: play_again0.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月10日 星期二 12时44分59秒 *********************************************************/ #include<stdio.h> #include<termios.h> #define QUESTION "Do you want another transaction" int get_reponse(char*); //简单控制台输入并反馈 int main(){ int response; response = get_reponse(QUESTION); return response; } int get_reponse(char* s){ printf("%s (y/n)?",s); while(1){ switch(getchar()){ case 'y': case 'Y':return 0; case 'n': case 'N': case EOF:return 1; } } }
play_again1.c
/****************************************************** > File Name: play_again1.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月10日 星期二 12时44分59秒 ******************************************************/ #include<stdio.h> #include<termios.h> #define QUESTION "Do you want another transaction" int get_reponse(char*); void set_crmode(); void tty_mode(int); //更改终端模式,让输入立刻反馈 int main(){ int response; //记录终端模式 tty_mode(0); //更改模式 set_crmode(); response = get_reponse(QUESTION); //回复模式 tty_mode(1); return response; } int get_reponse(char* s){ int input; printf("%s (y/n)?",s); while(1){ switch(input=getchar()){ case 'y': case 'Y':return 0; case 'n': case 'N': case EOF:return 1; default: printf("\ncannot understand %c,",input); printf("Please type y or n \n"); } } } //改变终端模式 void set_crmode(){ struct termios ttystate; tcgetattr(0,&ttystate); ttystate.c_lflag &= ~ICANON; ttystate.c_cc[VMIN] = 1; tcsetattr(0,TCSANOW,&ttystate); } void tty_mode(int how){ //静态局部变量记录原始终端设置模式 static struct termios original_mode; if(how==0) tcgetattr(0,&original_mode); else tcsetattr(0,TCSANOW,&original_mode); }
play_again2.c
/****************************************************** > File Name: play_again2.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月10日 星期二 12时44分59秒 *******************************************************/ #include<stdio.h> #include<termios.h> #define QUESTION "Do you want another transaction" int get_reponse(char*); void set_cr_noecho_mode(); void tty_mode(int); int main(){ int response; tty_mode(0); set_cr_noecho_mode(); response = get_reponse(QUESTION); tty_mode(1); return response; } int get_reponse(char* s){ printf("%s (y/n)?",s); while(1){ switch(getchar()){ case 'y': case 'Y':return 0; case 'n': case 'N': case EOF:return 1; } } } //更换终端模式,让程序关闭回显 void set_cr_noecho_mode(){ struct termios ttystate; tcgetattr(0,&ttystate); ttystate.c_lflag &= ~ICANON; ttystate.c_lflag &= ~ECHO; ttystate.c_cc[VMIN] = 1; tcsetattr(0,TCSANOW,&ttystate); } void tty_mode(int how){ static struct termios original_mode; if(how==0) tcgetattr(0,&original_mode); else tcsetattr(0,TCSANOW,&original_mode); }
play_again3.c
/******************************************************** > File Name: play_again3.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月10日 星期二 12时44分59秒 *********************************************************/ #include<stdio.h> #include<termios.h> #include<fcntl.h> #include<string.h> #include<unistd.h> #include<ctype.h> #define ASK "Do you want another transaction" #define TRIES 3 #define SLEEPTIME 2 #define BEEP putchar('\a') int get_reponse(char*,int); char get_ok_char(); void set_cr_noecho_mode(); void set_nodelay_mode(); void tty_mode(int); int main(){ int response; tty_mode(0); set_cr_noecho_mode(); set_nodelay_mode(); response = get_reponse(ASK,TRIES); tty_mode(1); return response; } int get_reponse(char* s,int t){ int input; printf("%s (y/n)?",s); //使用fflsuh强制将缓冲输出 fflush(stdout); while(1){ sleep(SLEEPTIME); input = tolower(get_ok_char()); if(input=='y') return 0; if(input=='n') return 1; if(t--==0) return 2; BEEP; } } char get_ok_char(){ int c; while((c=getchar())!=EOF&&strchr("yYnN",c)==NULL); return c; } void set_cr_noecho_mode(){ struct termios ttystate; tcgetattr(0,&ttystate); ttystate.c_lflag &= ~ICANON; ttystate.c_lflag &= ~ECHO; ttystate.c_cc[VMIN] = 1; tcsetattr(0,TCSANOW,&ttystate); } //使用fcntl设置非阻塞输入 void set_nodelay_mode(){ int termflags; termflags = fcntl(0,F_GETFL); termflags |= O_NDELAY; fcntl(0,F_SETFL,termflags); } void tty_mode(int how){ static struct termios original_mode; //静态局部变量记录原始输入设置 static int original_flags; if(how==0){ tcgetattr(0,&original_mode); original_flags=fcntl(0,F_GETFL); }else{ tcsetattr(0,TCSANOW,&original_mode); fcntl(0,F_SETFL,original_flags); } }
sigdemo1.c
/******************************************************** > File Name: sigdemo1.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月10日 星期二 14时52分15秒 ********************************************************/ #include<stdio.h> #include<signal.h> #include<unistd.h> int main(){ void f(int); //设置SIGINT信号对应处理函数f signal(SIGINT,f); for(int i=0;i<5;++i){ printf("hello\n"); sleep(1); } return 0; } void f(int signum){ printf("OUCH! \n"); }
sigdemo2.c
/******************************************************** > File Name: sigdemo2.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月10日 星期二 14时52分15秒 *********************************************************/ #include<stdio.h> #include<signal.h> #include<unistd.h> int main(){ //忽略信号SIGINT signal(SIGINT,SIG_IGN); printf("you can't stop me!\n"); while(1){ sleep(1); printf("hello\n"); } return 0; }
play_again4.c
/******************************************************* > File Name: play_again4.c > Author: Duke-wei > Mail: 13540639584@163.com > Created Time: 2017年10月10日 星期二 12时44分59秒 ********************************************************/ #include<stdio.h> #include<termios.h> #include<fcntl.h> #include<string.h> #include<unistd.h> #include<ctype.h> #include<signal.h> #include<stdlib.h> #define ASK "Do you want another transaction" #define TRIES 3 #define SLEEPTIME 2 #define BEEP putchar('\a') int get_reponse(char*,int); char get_ok_char(); void set_cr_noecho_mode(); void set_nodelay_mode(); void tty_mode(int); void ctrl_c_handler(int); int main(){ int response; tty_mode(0); //设置不会显 set_cr_noecho_mode(); //设置非阻塞输入 set_nodelay_mode(); //设置信号处理函数 signal(SIGINT,ctrl_c_handler); //忽略退出信号 Ctrl-\ signal(SIGQUIT,SIG_IGN); response = get_reponse(ASK,TRIES); tty_mode(1); return response; } int get_reponse(char* s,int t){ int input; printf("%s (y/n)?",s); fflush(stdout); while(1){ sleep(SLEEPTIME); input = tolower(get_ok_char()); printf("input :%c\n",input); fflush(stdout); if(input=='y') return 0; if(input=='n') return 1; if(t--==0) return 2; BEEP; } } char get_ok_char(){ int c; while((c=getchar())!=EOF&&strchr("yYnN",c)==NULL); return c; } void set_cr_noecho_mode(){ struct termios ttystate; tcgetattr(0,&ttystate); ttystate.c_lflag &= ~ICANON; ttystate.c_lflag &= ~ECHO; ttystate.c_cc[VMIN] = 1; tcsetattr(0,TCSANOW,&ttystate); } void set_nodelay_mode(){ int termflags; termflags = fcntl(0,F_GETFL); termflags |= O_NDELAY; fcntl(0,F_SETFL,termflags); } void tty_mode(int how){ static struct termios original_mode; static int original_flags; static int stored = 0; if(how==0){ tcgetattr(0,&original_mode); original_flags=fcntl(0,F_GETFL); stored = 1; }else if(stored){ tcsetattr(0,TCSANOW,&original_mode); fcntl(0,F_SETFL,original_flags); } } void ctrl_c_handler(int signum){ tty_mode(1); exit(1); }
相关文章推荐
- UNIX-LINUX编程实践教程->第五章->实例代码注解->echostate.c
- Unix-Linux编程实践教程——第十二章
- UNIX-LINUX编程实践教程->第二章->实例代码注解->more01
- 《Unix-Linux编程实践教程》读书笔记(三)
- Unix-Linux编程实践教程——第五章
- 一句话读书之unix-linux编程实践教程
- UNIX-LINUX编程实践教程->第八章->实例代码注解->写一个简单的shell
- Unix/Linux 编程实践教程 第7章 笔记(1)
- Unix-Linux编程实践教程——第九章
- Unix-Linux编程实践教程——第十三章
- Unix/Linux 编程实践教程 第6章 笔记
- 《Unix-Linux编程实践教程》读书笔记(七)
- Unix-Linux编程实践教程——第三章
- UNIX-LINUX编程实践教程->第二章->实例代码注解->who01
- UNIX-LINUX编程实践教程->第八章->实例代码注解->写一个简单的shell->在shell中启动另一个程序
- UNIX-LINUX编程实践教程->第二章->实例代码注解->cp1
- Unix-linux编程实践教程
- Unix/linux 编程实践教程 ---------- 服务器-客户端编程
- Unix-Linux编程实践教程——第十四章
- Unix-Linux编程实践教程——第二章