Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Unix-Linux编程实践教程-chapter06-signal

Unix-Linux编程实践教程-chapter06-signal

作者头像
零式的天空
发布于 2022-03-02 08:56:23
发布于 2022-03-02 08:56:23
1.2K00
代码可运行
举报
文章被收录于专栏:零域Blog零域Blog
运行总次数:0
代码可运行

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

有些程序处理从特定设备来的数据.这些与特定设备相关的程序 必须控制与设备的链接.Unix系统中最常见的设备是终端

终端驱动程序有很多设置.各个设置的特定值决定了终端驱动程序的模式. 为用户编写的程序通常需要设置终端驱动程序为特定的模式

键盘输入分为三类,终端驱动程序对这些输入做不同的处理.大多数键 代表常规数据,他们从驱动程序传输到程序,有些键调用驱动程序中的编辑 函数.如果按下删除键,驱动程序将前一个字符从他的行缓冲中删除,并将 命令发送到终端屏幕,使之从显示器中删除字符.最后,有些键调用处理 控制函数.Ctrl-C键告诉驱动程序调用内核中某个函数,这个函数给进程 发送一个信号.终端驱动程序支持若干种处理控制函数,他们都通过发送信号到 进程来实现控制

信号是从内核发送给进程的一种简短消息.信号可能来自用户,其他进程,或 内核本身.进程可以告诉内核,在他收到信号时需要做出怎样的响应

终端模式: 1 规范模式 常见模式,驱动程序输入的字符保存在缓冲,接收到回车才发送到程序

2 非规范模式 缓冲和编辑功能被关闭.stty -icanon

3 raw模式 每个处理步骤都被一个独立的位控制

由进程的某个操作产生的信号被称为同步信号 synchronous signals 由像用户击键这样的进程外的事件引起的信号被称为异步信号 asynchronous signals

进程如何处理信号: 1 接受默认处理 2 忽略信号 3 调用一个函数

大多数signal都可以被捕获或者忽略,但有两个无法被忽略,是SIGKILL SIGSTOP

code

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

/*
 * play_again3.c
 * purpose: ask if user wants another transaction
 * method: set tty into chr-by-chr mode and no-echo mode
 *          set tty into no-delay mode
 *          read char, return result
 * returns: 0 => yes, 1 => no, 2=> timeout
 * better: reset terminal mode on Interrupt
 */
#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>

#define ASK "Do you want another transaction"
#define TRIES 3     // max tries
#define SLEEPTIME 2 // time per try
#define BEEP putchar('\a')  // alert user

int main()
{
    int response;
    tty_mode(0);                        // save tty mode
    set_cr_noecho_mode();               // set -icanon, -echo
    set_nodelay_mode();                 // noinput => EOF
    response = get_response(ASK, TRIES);
    tty_mode(1);                        // restore tty mode
    return response;
}

int get_response(char * question, int maxtries)
{
    int input;
    printf("%s (y/n)?", question);
    fflush(stdout);                 // force output
    while(1)
    {
        sleep(SLEEPTIME);               // wait a bit
        input = tolower(get_ok_char()); // get next chr
        if (input == 'y')
            return 0;
        if (input == 'n')
            return 1;
        if (maxtries-- == 0)
            return 2;
        BEEP;
    }
}

// skip over non-legal chars and return y,Y,n,N or EOF
get_ok_char()
{
    int c;
    while ((c = getchar()) != EOF && strchr("yYnN", c) == NULL)
        ;
    return c;
}

set_cr_noecho_mode()
/*
 * purpose: put file descriptior 0 into chr-by-chr mode and noecho mode
 * method: use bits in termios
 */
{
    struct termios ttystate;
    tcgetattr(0, &ttystate);        // read curr. setting
    ttystate.c_lflag &= ~ICANON;    // no buffering
    ttystate.c_lflag &= ~ECHO;      // no echo either
    ttystate.c_cc[VMIN] = 1;        // get one char at a time
    tcsetattr(0, TCSANOW, &ttystate);   // install setting
}

set_nodelay_mode()
/* purose: put file descriptor 0 into no-delay mode
 * method: use fcntl to set bits
 * notes: tcsetattr() will do something similar, but it is complicated
 */
{
    int termflags;
    termflags = fcntl(0, F_GETFL);      // read curr. settings
    termflags |= O_NDELAY;              // flip on nodelay bit
    fcntl(0, F_SETFL, termflags);       // and install 'em
}

// how == 0 => save currentmode
// how == 1 => restore mode
// this version handles termios and fcntl flags
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);
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-07-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
RS232 串行通信:C++ 实现指南
在现代嵌入式系统和工业控制领域,RS232 串行通信仍然是一种不可或缺的技术。尽管 USB 和以太网等高速通信技术已经广泛应用,但在一些需要低速、简单通信的场景中,RS232 仍然是首选。本文将详细介绍如何在 C++ 中实现与 RS232 的通信,包括 Windows 和 Linux 平台的实现方法。
码事漫谈
2025/04/21
1380
RS232 串行通信:C++ 实现指南
linux系统kbhit的几种实现
printf("You pressed '%c'!/n", getchar());
用户4766018
2022/08/19
9190
Unix-Linux编程实践教程-chapter05-stty
内核在进程与外部世界之间交换数据.外部世界包括磁盘文件,终端与外部 设备,磁盘文件与终端的链接有相似之处也有差异
零式的天空
2022/03/02
5920
unix编程实践_7_事件驱动编程
在unxi/linux编程实践第七章的基础上完成的一个小的终端弹球游戏,先来个截图。
yifei_
2022/11/14
4620
unix编程实践_7_事件驱动编程
linux uart应用开发(ttyS*设备)《Rice linux 学习开发》
写这篇文章的原因:因为在linux开发串口应用的时候,遇到了问题,让遇到相同问题的人少走点弯路:
Rice加饭
2022/05/09
3.7K0
Linux UART 开发指南
介绍 Linux 内核中 UART 驱动的接口及使用方法,为 UART 设备的使用者提供参考。
韦东山
2023/02/25
6.7K0
Linux UART 开发指南
【驱动】串口驱动分析(四)-串口编程和调试方法
串口调试主要有 根据/proc系统信息确认串口状态,stty命令,编程调试 三种调试方法,下面我们分别具体介绍下。
嵌入式与Linux那些事
2024/05/20
5570
【驱动】串口驱动分析(四)-串口编程和调试方法
用C语言开发入门游戏FlappyBird
《flappy bird》是一款由来自越南的独立游戏开发者Dong Nguyen所开发的作品,游戏于2013年5月24日上线,并在2014年2月突然暴红。2014年2月,《Flappy Bird》被开发者本人从苹果及谷歌应用商店撤下。2014年8月份正式回归APP Store,正式加入Flappy迷们期待已久的多人对战模式。游戏中玩家必须控制一只小鸟,跨越由各种不同长度水管所组成的障碍。
莫浅子
2022/11/18
3.2K0
用C语言开发入门游戏FlappyBird
机器人编程趣味实践06-程序(节点)
每敲击一行指令,开启一个或多个程序,具体介绍参考(ROS 2节点-nodes-)。
zhangrelay
2021/12/02
4310
机器人编程趣味实践06-程序(节点)
Unix-Linux编程实践教程-chapter07-vediogame
有些程序的控制流很简单.而另外一些则要响应外部的事件.一个 视频游戏要响应时钟和用户输入,操作系统也要响应时钟和外设
零式的天空
2022/03/02
4540
C++随笔(五)三种实现串口通信的方式
要说最好用的是select的形式,防止漏掉发送过来的数据,缺点是需要单开一条线程独立出来串口服务用来接收数据 一般比较大的工程里还是结合着libevent来用吧。 一般形式
Pulsar-V
2019/08/08
7.5K0
终端I/O---ttyS3: 3 inp
#include <stdio.h> #include "time.h" #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> int main() {   struct termios opt;   int fd=-1;   int nread;   char buf[1024];   fd=open("/dev/ttyS3" ,O_RDONLY    |O_NONBLOCK); if(fd==-1)    {    printf("open /dev/ttyS3 error\n");    }   tcgetattr(fd,&opt);              //获取终端属性到opt   tcflush(fd,TCIOFLUSH);              //同时刷新收到的数据但是不读,刷新写入的数据但是不传送   cfsetispeed(&opt, B9600);                 //设置输入波特率   cfsetospeed(&opt, B9600);             //设置输出波特率   opt.c_cflag&=~CSIZE;              //(不用     )字符长度掩码。取值为 CS5, CS6, CS7, 或 CS8。   opt.c_cflag |=CS8;              //取值为CS8   opt.c_cflag &= ~PARENB;              //(不用     )允许输出产生奇偶信息以及输入的奇偶校验。   opt.c_iflag &= ~INPCK;              //(不用     )启用输入奇偶检测。   opt.c_cflag &= ~CSTOPB;              //(不用     )设置两个停止位,而不是一个   opt.c_cflag &= ~CRTSCTS;              //(不用     )硬件流控   opt.c_cc[VTIME] = 150;              //非 canonical 模式读时的延时,以十分之一秒为单位   opt.c_cc[VMIN] = 0;                      //非 canonical 模式读的最小字符数   opt.c_lflag    &= ~(ICANON | ECHO) ;              //(不用     )启用标准模式 (canonical mode)允许使用              //特殊字符 EOF, EOL, EOL2, ERASE, KILL, LNEXT, REPRINT,               //和 WERASE,以及按行的缓冲。              //(不用     )回显输入字符。   tcflush(fd,TCIOFLUSH);   tcsetattr(fd,TCSANOW,&opt);              //改变立即发生 while(1)     {         nread = read(fd,buf,1000);         //printf("nread=%d\n",nread);         //if(nread !=-1 )    printf("%s",buf);//打印数据         sleep(2);         memset(buf,0x0,1024);     } if(fd!=-1) close(fd);   return 0; }
py3study
2020/01/06
9860
程序员探案之被吃掉的串口数据
---- 2018电影春节档,唐人街探案居然拔得头筹,原因我分析了下,个人觉得 多数人都有一颗了解真相的心吧 程序员的世界里,总是充满着悬念,而带来悬念的就是挥之不去的bug 修复bug,就像侦办一起案件 我就蹭蹭热度 来个 程序员探案 系列吧 ---- 直击"案发"现场 前两天做嵌入式开发的一哥们在用ARM和一串口设备进行通信时, 碰到了诡异的问题,受尽折磨的他告诉我: 数据被"吃掉"了,还有人"调包" "案情"分析 通过大量分析发送和接收的数据对比,看出了些端倪 数据被"吃掉" 程序在接收数据时 0x
用户2196567
2018/07/02
8440
Linux串口编程示例
termios是用于终端I/O的较新(现在已经有几十年历史)Unix API。在termios的帮助下执行串行I/O的程序剖析如下:
知否知否应是绿肥红瘦
2025/02/19
9860
Linux串口编程示例
UART 接口测试「建议收藏」
组合键 Ctrl+a 进入设置状态 按z打开帮助菜单,或者直接输入菜单对应的字母即可 S键:发送文件到目标系统中 W键:自动卷屏。当显示的内容超过一行之後,自动将後面的内容换行 C键:清除屏幕的显示内容 B键:浏览minicom的历史显示 X键:退出minicom
全栈程序员站长
2022/10/05
1.3K0
Unix-Linux编程实践教程-chapter02-who
Unix 系统把数据存放在文件中,可以通过以下系统调用来操作文件: open(filename, how) creat(filename, mode) read(fd, buffer, amt) write(fd, buffer, amt) lseek(fd, distance, base) close(fd)
零式的天空
2022/03/02
1.3K0
Unix-Linux编程实践教程-chapter15-IPC
许多程序都包含一个或多个进程.进程间通过共享数据或传递数据进行通信.举例来说, 两个人通过使用Unix的talk命令进行对话,他们就运行了两个进程,将数据从键盘和socket 传输到屏幕和socket
零式的天空
2022/03/02
6620
Unix-Linux编程实践教程-chapter03-ls
磁盘上有文件和目录,文件和目录都有目录和属性.文件的内容可以是任意的数据, 目录的内容只能是文件名或者子目录名的属性
零式的天空
2022/03/02
4420
Unix-Linux编程实践教程-chapter01-more
在登陆过程中,当用户名和密码通过验证后,系统会启动一个叫做shell的进程,然后把 用户交给这个进程,由这个进程处理用户的请求,每个用户都有属于自己的shell进程
零式的天空
2022/03/02
5300
嵌入式Linux系列第7篇:操作UART
串口是我们实际工作中经常使用的一个接口,比如我们在Linux下使用的debug串口,它用来登录Linux系统,输出log。另外我们也会使用串口和外部的一些模块通信,比如GPS模块、RS485等。这里对Linux下串口使用做个总结,希望对大家有所帮助。
用户2366192
2021/05/31
3.3K0
相关推荐
RS232 串行通信:C++ 实现指南
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验