第6章 为用户编程:终端控制和信号

终端模式:

在这里插入图片描述
关闭规范输入,即时响应
在这里插入图片描述
开启非阻塞输入
在这里插入图片描述
在这里插入图片描述

信号
●信号从哪来以及有哪些
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
●如何处理信号
在这里插入图片描述
在这里插入图片描述

综合运用以上知识的是否继续代码

/* play_again4.c
 * When no is input , restore the tty settings
 */

 #include <stdio.h>
 #include <termios.h>
 #include <fcntl.h>
 #include <string.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <ctype.h>

 #define ASK "Do you want to play again?"
 #define TRIES 3	//尝试次数
 #define SLEEPTIME 2	//每次睡眠时间
 #define BEEP putchar('\a');	//BEEP

void ctrl_c_handler(int);
int get_response(char * , int );
int get_ok_char(void);
void set_nodelay_mode(void);
void set_cr_noecho_mode(void);
void tty_mode(int); 

 int main()
 {
     int response ;
     tty_mode(0);
     set_cr_noecho_mode();
     set_nodelay_mode();

     signal(SIGINT , ctrl_c_handler) ; //收到SIGINT信号调用函数
     signal(SIGQUIT , SIG_IGN );	//忽略QUIT信号

     response = get_response(ASK , TRIES );

     tty_mode(1);
     return response ;
 }

void ctrl_c_handler(int signum )
{
    tty_mode(1) ; //进程被退出时调用函数还原设置
    exit(1) ;
}

 int get_response(char * qiz , int tries )
 {
     int input ;
     int maxtries = tries ;
     printf("%s(y/n)" , qiz);
     //fflush(stdout);	//强迫缓冲区写入
     while(1)
     {
        BEEP ;
        sleep(SLEEPTIME);	//休眠
        input = tolower(get_ok_char());
        if(input == 'y')
        {
            printf("\n");
            return 0 ;
        }
        if(input == 'n')
        {
            printf("\n");
            return 1 ;
        }
        if(maxtries -- <= 0 )	//尝试次数用完就退出
        {
            printf("\n");
            return 2 ;
        }
        BEEP ;
     }
 }
 
int get_ok_char(void)	//获得有效输入
{
    int c ;
    while( (c = getchar() ) != EOF && strchr("yYnN" , c ) == NULL )
        ;
    return c ;
}

void set_cr_noecho_mode(void)
{
    struct  termios ttystate ;
    tcgetattr(0 , &ttystate);
    ttystate.c_lflag &= ~ICANON ;   // No Buffering
    ttystate.c_lflag &= ~ECHO ;		//No ECHO
    ttystate.c_cc[VMIN] = 1 ;   //Get one char one time 
    tcsetattr( 0 , TCSANOW , &ttystate);    
}

void set_nodelay_mode(void)		//调用fcntl设置非阻塞输入
{
    int termflags ;
    termflags = fcntl(0 , F_GETFL);
    termflags |= O_NDELAY ;
    fcntl(0 , F_SETFL , termflags) ;
}

void tty_mode(int mode)
{
    static struct termios original_mode ;// 设置静态结构体变量
    if(mode == 0 )
    {
        tcgetattr( 0 , & original_mode);// 存储原有设置
    }
    else
    {
        //还原原有设置
        if( tcsetattr(0 , TCSANOW , & original_mode) == -1 )
        {
            perror("Restore tty settings failed!\n");
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值