您的位置:首页 > 运维架构 > Linux

Unix-Linux编程实践教程——第六章

2017-10-21 13:56 405 查看

章节概要

本章节主要讲解终端控制以及信号,通过对终端输入过程的分析以及一个小游戏,让我们了解终端控制以及信号

终端模式

规范模式:驱动程序输入的字符保存在缓冲区,并且仅在接受到回车键时才将缓冲的字符发送到程序。

非规范模式:当缓冲和编辑功能被关闭时,连接被称为非规范模式。终端处理器仍旧进行特定字符处理,例如处理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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: