一、综述

终端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(上)的更多相关文章

  1. Linux系统编程@终端IO

    Linux系统中终端设备种类  终端是一种字符型设备,有多种类型,通常使用tty 来简称各种类型的终端设备.终端特殊设备文件一般有以下几种: 串行端口终端(/dev/ttySn ) ,伪终端(/dev ...

  2. 低级终端IO

    低级终端IO 程序会需要对输入输出进行比简单的文件操作更为精确的控制.POSX提供了一套接口允许程序控制终端驱动程序的行为,这套接口称为通用终端接口(GIT). 需要改变终端设置的例子 标准输入输出, ...

  3. linux终端io笔记

    简介 终端的两种工作模式:以行为单位的工作模式,以字符数或时间为单位自定义模式 终端判断函数: int isatty(int fd) 终端属性的获取与设置: int tcgetattr(int fd, ...

  4. linux 终端 查看上一页

    问题描述: 我在终端中使用”dpkg -l”命令显示主机中安装的软件时,发现内容很多,而当命令执行完毕后,只显示终端最后一屏的内容.前面的都无法查看,这个是很让人憋屈的.下面就这一个问题说一下我的解决 ...

  5. commons io上传文件

    习惯了是用框架后,上传功能MVC框架基本都提供了.如struts2,springmvc! 可是假设项目中没有使用框架.而是单纯的使用jsp或servlet作为action,这时我们就能够使用commo ...

  6. 解决 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 看到如下输出结果 ; <& ...

  7. spartan6不能直接把时钟连到IO上

    1.问题的提出:spartan6中不允许时钟信号直接连到IO口上面? 2.解决办法: ODDR2的使用 ODDR2Primitive: Double Data Rate Output D Flip-F ...

  8. Redis持久化磁盘IO方式及其带来的问题   有Redis线上运维经验的人会发现Redis在物理内存使用比较多,但还没有超过实际物理内存总容量时就会发生不稳定甚至崩溃的问题,有人认为是基于快照方式持

    转自:http://blog.csdn.net/kaosini/article/details/9176961 一.对Redis持久化的探讨与理解    redis是一个支持持久化的内存数据库,也就是 ...

  9. debian 7 终端上无法调出输出法

    debian 7 终端konsole上无法调出输出法,无法输入汉字的问题解决方案, export GTK_IM_MODULE=fcitxexport QT_IM_MODULE=fcitxexport ...

随机推荐

  1. Java 注释类之常用元注解

    Java 注释类之常用元注解 自定义Java注释类时,我们使用方式如下:   @Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD ...

  2. 每次运行caffe代码之前需要考虑修改的地方

    Train阶段: (1)       train.sh中的solver.prototxt路径 (2)       train.sh中的caffemodel路径 (3)       train.sh中的 ...

  3. Java8 利用Lambda处理List集合循环给另外一个List赋值过滤处理

    1.利用stream().forEach()循环处理List; List<String> list = Lists.newArrayList();//新建一个List 用的google提供 ...

  4. postgre 导出单表和导入

    pg除了可以通过dump的方式导入和导出.如果只是导出数据,可以直接使用copy 导出 COPY user TO '/tmp/data/test.csv' WITH csv; COPY user(na ...

  5. cocos2d-x 学习资源

    1. http://cocos2d.cocoachina.com/resource(中文),也有示例,文中缺少的图片可以从下面的网址下载 对应的英文是: http://cocos2d-x.org/wi ...

  6. 监控命令之tsar

    1.1 tsar是什么? tsar是淘宝自己开发的一个采集工具(类似于sar工具),主要用来收集服务器的系统信息(如cpu,io,mem,tcp等),以及应用数据(如squid haproxy ngi ...

  7. ionic build - 修改gradle路径提升速度和成功率

    ionic build 不成功很多时候是因为下载gradle太慢, 我们可以下载好gradle然后修改配置文件, 从而省去这个烦人的下载过程 1. 下载报错时的gradle zip文件, 或者直接查看 ...

  8. docker部署maven私有仓库 nexus3

    docker pull sonatype/nexus3: docker run -d --name nexus3.x --network host -v /volume-data/nexus3/nex ...

  9. maven本地库与私服比对,查找缺失jar包

    项目中遇到的一个问题,因为要切换开发环境(新环境不能联网,且私服上的jar包信息不全),需要将本地仓库(项目使用本地仓库能够正常编译)中有而私服上没有的jar包整理出来(名称.版本号等),提供给第三方 ...

  10. ceph 生成rpm包

    概述 从ceph的源码build出rpm包: #git clone --recursive https://github.com/ceph/ceph.git #./instal-dep.sh 以上两点 ...