6章 为用户编程:终端控制和信号
6.1
1.软件工具:对磁盘文件和设备文件不加以区分的程序
2.用户程序:针对特定设备编写的程序
--------这些程序设置终端驱动程序的击键和输出方式。
6.2 终端驱动程序的模式
1.实现一个程序时,驱动程序自动完成的处理功能:
(1)①规范模式:缓冲、编辑(删除字符、单词或整行按键)
②特定字符处理:把\r转化成\n,Ctrl-C
③其他:例如回显
(2)①编辑功能的特定键在驱动程序里设置,可通过stty或系统调用tcsetattr来修改。
(例如:程序结束按键,可以不用ctrl+c,改成别的按键表示这个功能。)
②总结:每个处理功能都被一个独立的位控制。程序可以随机关闭这些处理步骤。
2.终端驱动程序的模式:(1)规范模式:缓冲、编辑
(2)非规范模式:关闭规范模式处理。仍有特定字符处理功能。
(3)raw模式:所有的处理功能都被关闭
6.3编写一个用户程序play_again.c
play_again.c的逻辑:对用户显示提出问题
接受输入
如果是y,返回0;如果是n,返回1。
play_again0.c
实现以上功能。
但是没有错误输入的处理。
play_again1.c
改进:(1)关闭缓冲。接受和处理字符不等待回车。
(2)设置每次只可读入一个字符。读入一个字符边开始处理。
-----(通过设置终端驱动程序的函数来实现)
缺点:每次输入一个错误字符,提示一串错误信息让人觉得比较烦。
play_again2.c
改进:(1)关闭回显位置。(通过设置终端驱动程序的函数来实现)
(2)错误信息直接或略不在提示。(把错误信息提示代码删掉)
缺点:程序一直等待用户输入’y’/‘n’(阻塞)。如果人走了就一直阻塞。
play_again3.c
改进:(1)使用fcntl关闭阻塞模式
(2)使用sleep实现:先检查是否有输入,如果没有则睡眠2s在继续检查
maxtrie实现:如果3次输入错误,程序结束退出。
===================================================
6.4 信号
6.4.1ctrl+c终断当前运行的程序
过程:(1)用户键入Ctrl+C
(2)信号系统发送 SIGINT信号:①驱动程序收到字符
②匹配VINTR和ISIG的字符被开启
③驱动程序调用信号系统
④信号系统发送 SIGINT信号
(3)进程收到SIGINT信号
(4)进程终止
6.4.2信号是什么
1.信号是什么?
(1)信号:由单个词组成的消息。
例如 信号:绿灯、停止牌
消息:走、 停
(2)每个信号都有一个数字编码。(查看信号列表)
2.信号从哪里来?--------------信号来自内核。
有生成信号的请求后,内核发出信号。
生成信号的请求来自:
(1)用户:输入按键
(2)内核:当执行出错时,内核给进程发送错误信号。
(3)进程。一个进程可以通过系统调用kill给另一个进程发送信号。
一个进程可以和另一个进程通过信号通信。
3.分类: 同步信号:由进程的某个操作产生的信号。
异步信号:进程外的事件引起的信号。(例如,用户击键)
4.信号可用来做什么? 例如信号可以杀死进程。
6.4.3进程如何处理信号
1.进程通过系统调用signal()函数告诉内核,它要如何处理信号。
result = signal(int sig, void(*fun)(int));
函数功能:向系统注册。(在哪个进程中注册,就在哪个进程中起作用。)
之后只要sig信号发生,系统停止当前进程,并调用信号处理函数fun。
当函数执行完毕,继续原来进程。-------即,实现终断。
返回:成功返回:指向前一个处理函数的指针。
遇到错误:-1.
2.进程接受到信号后,有三种处理方式:
(1)接受默认处理(一般是进程消亡) signal( SIGNIT, SIG_DFL );
(2)忽略信号 signal( SIGNIT, SIG_IGN);
(3)调用一个函数。 signal( SIGNIT, 函数fun);
signal的位置?
6.7 为设备编程
编写终端控制程序的三个方面:(1)学习驱动程序的属性和如何控制连接
(2)学习应用程序的特定需求
(3)学习如何处理信号---中断的一种形式