终端IO(上)
一、综述
终端IO有两种不同的工作方式:
- 规范方式输入处理。在这种方式中,终端输入以行为单位进行处理。对于每个读要求,终端驱动程序最多返回一行。
- 非规范方式输入处理。输入字符不以行为单位进行装配
如果不做特殊处理,则默认方式是规范方式。vi编辑程序使用非规范方式,其原因是其命令是由不以换行符终止的一个或几个字符组成。
POSIX.1定义了11个特殊输入字符。其中9个可以改变
终端设备一般位于内核中的终端驱动程序所控制的。每个终端设备有一个输入队列,一个输出队列,见下图:

对此图要说明以下几点:
- 如果需要回送,则在输入队列和输出队列中间有一个隐含的连接。
- 输入队列的长度MAX_INPUT是有限值,当一个特定设备的输入队列已填满,各系统实现有所不同,大多数UNIX系统会送响铃字符。
- 图中没有显示另一个输入限制MAX_CANON,它是一个规范输入行中的最大字节数。
- 虽然输出队列通常也是有限长度,但是程序不能存取定义其长度的常数。这是因为当输出队列要填满时,内核使写进程睡眠直至写队列中有可用的空间,所以程序无需关心该队列的长度。
大多数UNIX系统在一个称为终端行规程(terminal line discipline)的模块中进行规范处理。它是位于内核类属读、写函数和实际设备驱动程序之间的模块,见下图

所有我们可以检测和更改的终端设备特性都包含在termios结构中。该结构在头文件<termios.h>中定义。
struct termios {
tcflag_t c_iflag; /* input flag */
tcflag_t c_oflag; /* output flags */
tcflag_t c_cflag; /* control flags */
tcflag_t c_lflag; /* local flags */
cc_t c_cc[NCCS]; /* control characters */
};
粗略而言,输入标志由终端设备驱动程序用来控制输入特性(剥除输入字节第8位,允许输入奇偶校验等等),输出标志则控制输出特性(执行输出处理,将新行映照为CR/LF等),控制标志影响到RS-232串行线(忽略调制解调器的状态线,每个字符的一个或两个停止位等等),本地标志影响驱动程序和用户之间的界面(回送的开或关,可试的擦除符,允许终端产生的信号,对后台作业输出的控制停止信号等)。
类型tcflag_t的长度是以保持每个标志值。它经常被定义为unsigned long。c_cc数组包含了所有可以更改的特殊字符。NCCS是该数组的长度,POSIX.1定义为11,咯实现有所不同。cc_t类型的长度足以保持每个专用字符,典型的是unsigned char。
下表列出了所有可以更改以影响终端设备特性的终端标志。


下表列出了POSIX.1定义对终端设备进行操作的各个函数。

对终端设备,POSIX.1没有使用ioctl,而使用了上表中列出的12个函数。这样做的理由是:对于终端设备的ioctl函数,最后一个参数的数据类型随执行动作的不同而不同。
上表中12个函数之间的关系见下图:

二、特殊输入字符
POSIX.1定义了11个在输入时做特殊处理的字符。SVR4 另外加了6个特殊字符,4.3+BSD则加了7个。下表列出了这些字符

11个特殊字符中,9个可以更改为任何值。不能更改的是换行符\n和回车符\r。为了进行修改,只要更改termios结构中c_cc数组的相应项。该数组中的元素都用名字作为下标进行引用,每个名字都以字母V开头。
三、获取和设置终端属性
使用函数tcgetattr和tcsetattr可获得/设置termios。这样就可以检测和修改各种终端选择标志和特殊字符,以使终端按我们所希望的方式进行操作。
#include <termios.h>
int tcgetattr(int filedes, struct termios *termpptr);
int tcsetattr(int filedes, int opt, const struct termios *termpptr);\
返回值: 成功为1,出错为-1
因为这两个函数只对终端设备进行操作,所以若filedes并不引用一个终端设备则出错返回,error设置为ENOTTY
tcsetattr的参数opt使我们可以指定在什么时候新的终端属性才起作用。opt可以指定为以下常数中的一个:
- TCSANOW 更改立即发生
- TCSADRAIN 发送了所有输出后更改才发生。若更改输出参数则应使用此选择项
- TCSAFLUSH 发送了所有输出后更改才发生。更进一步,在更改发生时未读的所有输入数据都被删除(刷清)。
tcsetattr函数的返回值易于产生混淆。如果执行了任意一种所要求的动作,即使未能执行所有要求的动作,它也返回0(表示成功)。如果函数返回0,则我们有必要调用tcgetattr获取实际终端属性与希望的终端属性做对比,判断是否真正的修改成功。
终端IO(上)的更多相关文章
- Linux系统编程@终端IO
Linux系统中终端设备种类 终端是一种字符型设备,有多种类型,通常使用tty 来简称各种类型的终端设备.终端特殊设备文件一般有以下几种: 串行端口终端(/dev/ttySn ) ,伪终端(/dev ...
- 低级终端IO
低级终端IO 程序会需要对输入输出进行比简单的文件操作更为精确的控制.POSX提供了一套接口允许程序控制终端驱动程序的行为,这套接口称为通用终端接口(GIT). 需要改变终端设置的例子 标准输入输出, ...
- linux终端io笔记
简介 终端的两种工作模式:以行为单位的工作模式,以字符数或时间为单位自定义模式 终端判断函数: int isatty(int fd) 终端属性的获取与设置: int tcgetattr(int fd, ...
- linux 终端 查看上一页
问题描述: 我在终端中使用”dpkg -l”命令显示主机中安装的软件时,发现内容很多,而当命令执行完毕后,只显示终端最后一屏的内容.前面的都无法查看,这个是很让人憋屈的.下面就这一个问题说一下我的解决 ...
- commons io上传文件
习惯了是用框架后,上传功能MVC框架基本都提供了.如struts2,springmvc! 可是假设项目中没有使用框架.而是单纯的使用jsp或servlet作为action,这时我们就能够使用commo ...
- 解决 docker.io 上拉取 images Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout
处理方式 使用如下命令获取 registry-1.docker.io 可用的 ip dig @114.114.114.114 registry-1.docker.io 看到如下输出结果 ; <& ...
- spartan6不能直接把时钟连到IO上
1.问题的提出:spartan6中不允许时钟信号直接连到IO口上面? 2.解决办法: ODDR2的使用 ODDR2Primitive: Double Data Rate Output D Flip-F ...
- Redis持久化磁盘IO方式及其带来的问题 有Redis线上运维经验的人会发现Redis在物理内存使用比较多,但还没有超过实际物理内存总容量时就会发生不稳定甚至崩溃的问题,有人认为是基于快照方式持
转自:http://blog.csdn.net/kaosini/article/details/9176961 一.对Redis持久化的探讨与理解 redis是一个支持持久化的内存数据库,也就是 ...
- debian 7 终端上无法调出输出法
debian 7 终端konsole上无法调出输出法,无法输入汉字的问题解决方案, export GTK_IM_MODULE=fcitxexport QT_IM_MODULE=fcitxexport ...
随机推荐
- spring cloud:Edgware.RELEASE版本中zuul回退方法的变化
Edgware.RELEASE以前的版本中,zuul网关中有一个ZuulFallbackProvider接口,代码如下: public interface ZuulFallbackProvider { ...
- Linux及MacOSX中使用zsh
via : http://leochin.com/linux-macosx-shell-zsh/ Linux及MacOSX中使用zsh zsh是另一种Shell,类似bash,tcsh等等,只是多了一 ...
- UVa 127 - "Accordian" Patience POJ 1214 链表题解
UVa和POJ都有这道题. 不同的是UVa要求区分单复数,而POJ不要求. 使用STL做会比較简单,这里纯粹使用指针做了,很麻烦的指针操作,一不小心就错. 调试起来还是很费力的 本题理解起来也是挺费力 ...
- spyder 安装
https://www.cnblogs.com/pcat/p/5398997.html
- FDMEMTABLE将修改后的数据序列为JSON
FDMEMTABLE将修改后的数据序列为JSON procedure TForm1.Button3Click(Sender: TObject); var memtable: TFDMemTable; ...
- 2014年新一代的报表利器 Qlik Sense Desktop 初步体验
点击进入 QlikView/QlikSense 社区 交流群:432998033 Qlik Sense Desktop 的案例展示 先上几个刚刚边看边学完成的几个报表案例效果 (如果图片显示不正常, ...
- weex开发错误汇总
weex run serve 报UglifyJS错 ANDROID_HOME环境变量 weex build android需要ANDROID_HOME, 请配置 D:\adt-windows-x86_ ...
- HTML5 完美解决javascript中iphone手机和android手机复制文本到剪切板问题
1.执行以下解决方案条件:(这个是原理) ①执行复制方法时 所复制文字不能被任何 块级元素和行内块元素和行内元素遮盖否则无效:(解决方案:将文本通过绝对定位或其他方式移除屏幕外) ②ios中不能复制属 ...
- JEECG中表单提交的中断
JEECG平台中基于form表单封装了<t:formvalid>标签,对应实现的类为FormValidationTag.java文件. 很多时候在正式向后台提交数据前想要做判断处理,若通过 ...
- 2018年末--积极拥抱h5.转载 大前端时代来临,我们何去何从?
1.大前端时代是什么? 大前端时代是WEB统一的时代,利用html5或者6甚至7,不但可以开发传统的网站,做炫酷的网页动态效果,更可以采用BS架构应用程序.开发手机端web应用.移动端Native应用 ...