终端I/O之综述

终端I/O有两种不同的工作模式:

  1. 规范模式输入处理(Canonical mode input processing)。在这种模式中,终端输入以行为单位进行处理。对于每个读要求,终端驱动程序最多返回一行。
  2. 非规范模式输入处理(Noncanonical mode input processing)。输入字符并不组成行。

如果不作特殊处理,则默认模式是规范模式。

V7和较早的BSD风格类的终端驱动程序支持三种终端输入模式:(a)精细加工模式(输入组成行,并对特殊字符进行处理);(b)原始模式(输入不组成行,也不对特殊字符进行处理);(c)cbreak模式(输入不组成行,但对某些特殊字符进行处理)。

终端设备是由一般位于内核中的终端驱动程序控制的每个终端设备有一个输入队列和一个输出队列,如图18-1所示。

图18-1 终端设备的输入、输出队列逻辑结构

将图18-1转换为如下图所示更容易理解:

对此图要说明以下几点:

  1. 如果打开了回显功能,则在输入队列和输出队列之间有一个隐含的连接。
  2. 输入队列的长度MAX_INPUT是有限值,当一个特定设备的输入队列已经填满时,系统对此作何种处理依赖于实现。大多数UNIX系统的处理方式是回显响铃字符。
  3. 图中没有显示另一个输入限制MAX_CANON,它是一个规范模式输入行中的最大字节数。
  4. 虽然输出队列通常也是有限长度,但是程序并不能获得这个定义其长度的常量,这是因为当输出队列将要填满时,内核使写进程休眠直至写队列中有可用的空间,所以程序无需关心该队列的长度。
  5. 我们可以使用tcflush函数刷清(flush)输入或输出队列。

     

大多数UNIX系统在一个称为终端行规程(terminal line discipline)的模块中进行规范处理。它是位于内核通用读、写函数和实际设备驱动程序之间的模块(见图18-2)。

图18-2 终端行规程

所有我们可以检测和更改的终端设备特性都包含在termios结构中。该结构定义在头文件<termios.h>中。

struct termios {

tcflag_t        c_iflag;        /* input flags */

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-32串行线(忽略调制解调器的状态线、每个字符的一个或两个停止位等等),本地标志影响驱动程序和用户之间的接口(回送的开或关、可视的擦除字符、终端产生的信号启用以及对后台输出的作业控制停止信号等)。

    类型tcflag_t的长度足以保存每个标志值。它经常被定义为unsigned int或者unsigned long。c_cc数组包含了所有可以更改的特殊字符。NCCS是该数组的长度,一般介于15-20之间(大多数UNIX系统定义的特殊字符较POSIX所定义的11个要多)。cc_t类型的长度足以保存每个特殊字符,而且它往往是unsigned char型的。

    表18-1至表18-4列出了所有可以进行更改以影响终端设备特性的终端标志。注意,虽然Single UNIX Specification定义了所有平台都支持的公共子集,但是各平台还有自己的扩充部分。

表18-1 c_cflag终端标志

表18-2 c_iflag终端标志

表18-3 c_lflag终端标志

表18-4 c_oflag终端标志

 

表18-5列出了Single UNIX Specification所定义的对终端设备进行操作(检测和更改终端设备的特性)的的各个函数。http://www.cnblogs.com/nufangrensheng/p/3513642.html中已说明了 tcgetpgrp、tcgetsid和tcsetpgrp函数。)

表18-5 终端I/O函数总览

注意,对终端设备,Single UNIX Specification没有使用经典的ioctl,而使用了表18-5中列出的13个函数。这样做的理由是:对于终端设备的ioctl函数,其最后一个参数的数据类型随执行动作的不同而不同。于是,这使得对参数进行类型检查成为不可能。

虽然对终端设备进行操作只有13个函数,但是表18-5中头两个函数(tcgetattr和tcsetattr)能处理大约70中不同的标志(见表18-至表18-4)。此外,对于终端设备有大量的选项可供使用,对一个特定设备(终端、调制解调器、激光打印机等等)还要决定所需的选项,这些都使对终端设备的处理变得异常复杂。

表18-5中列出的13个函数之间的关系如图18-3所示:

图18-3 与终端有关的函数之间的关系

posted @ 2014-03-01 22:15  ITtecman  阅读(1436)  评论(0编辑  收藏  举报