一、综述

终端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. EF6 简单增删改查示例代码

    示例一: private DbContext _dbContext; public DbContext CurrentContext { get { if (_dbContext == null) { ...

  2. centos npm 安装后 command not found

    ok,

  3. AVL树平衡旋转详解

    AVL树平衡旋转详解 概述 AVL树又叫做平衡二叉树.前言部分我也有说到,AVL树的前提是二叉排序树(BST或叫做二叉查找树).由于在生成BST树的过程中可能会出现线型树结构,比如插入的顺序是:1, ...

  4. Core Animation学习总结

    文件夹: The Layer Beneath The Layer Tree(图层树) The Backing Image(寄宿层) Layer Geometry(图层几何学) Visual Effec ...

  5. C# SpinWait 实现

    其实SpinWait的code 非常简单,以前看过很多遍,但是从来都没有整理过,整理也是再次学习吧. 我们先看看SpinWait的一些评论或者注意点吧:如果等待某个条件满足需要的时间很短,而且不希望发 ...

  6. IE10、IE11使用 __doPostBack 出现未定义问题

    在公司的老项目中分页控件使用了 __doPostBack 方式,在IE兼容模式下正常,在IE10.IE11中 __doPostBack 出现未定义问题. 百度查阅资料得知,这是微软NET环境下的一个B ...

  7. c++设计一个无法被继承的类

    要求是该类不能被继承,但是能够像正常的类一样使用.那么一下方法就不符合题目要求: 1.构造函数和析构函数设置为private.这样就不能定义一个类的实例 2.类似于singleton模式那样,定义一个 ...

  8. 微软BI 之SSAS 系列 - 多维数据集维度用法之二 事实维度(退化维度 Degenerate Dimension)

    这篇文章是基于上一篇 SSAS 系列 - 多维数据集维度用法之一 引用维度 Referenced Dimension 继续讲解多维数据集维度用法中的事实维度. 事实维度,顾名思义就是把事实表 Fact ...

  9. List or delete hidden files from command prompt(CMD)

    In Windows, files/folders have a special attribute called hidden attribute. By setting this attribut ...

  10. 关于PHP中的webshell

    一.webshell简介 webshell就是以asp.php.jsp或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门.黑客在入侵了一个网站后,通常会将asp或php后门文 ...