终端 I/O 综述

终端设备可认为是由内核中的终端驱动程序控制的。每个终端设备都有一个输入队列和输出队列。如下图所示。
[img]http://dl2.iteye.com/upload/attachment/0129/7795/19e52b16-e753-3d06-bec0-6e0595a59047.png[/img]
对该图要说明以下几点:
1)如果打开了回显功能,则在输入队列和输出队列之间有个隐含的连接。
2)当一个特定设备的输入队列中的字节数达到 MAX_INPUT(见[url=http://aisxyz.iteye.com/admin/blogs/2367287]unix限制[/url]一节)时,系统的行为将依赖于实现(大多数 UNIX 系统回显响铃字符)。
3)图中没有显示另一个输入限制 MAX_CANON,它是一个规范输入行的最大字节数。
4)虽然输出队列的长度通常也是有限的,但程序并不能获得该长度,因为内核会在输出队列将要填满时使写进程休眠,直到写队列中有可用的空间。
5)后面会介绍如何使用 tcflush 函数冲洗输入或输出队列,以及在介绍 tcsetattr 函数时,将了解到如何通知系统只有在输出队列为空时,才能改变一个终端的属性,也可以让它在改变终端属性时丢弃输入队列中的所有东西。
多数 UNIX 系统在一个称为终端行规程(terminal line discipline)的模块中进行全部的规范处理,可将其视作位于内核通用读、写函数和实际设备驱动程序之间的一个盒子,通过它我们能够设置终端的特殊字符(如退格、行删除、中断等)。如图所示。
[img]http://dl2.iteye.com/upload/attachment/0129/7797/2a8b439e-69c8-3ef8-920c-5620dc492d33.png[/img]
termios 结构包含了所有可以检测和更改的终端设备特性。

#include <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
};

其中,输入标志 c_iflag 通过终端设备驱动程序控制字符的输入(如剥除输入字节的第 8 位,允许输入奇偶校验),输出标志 c_oflag 则控制驱动程序输出(如执行输出处理、将换行符转换成 CR/LF),控制标志 c_cflag 影响 RS-232 串行线(如忽略调制解调器的状态线、每个字符的一个或两个停止位),本地标志 c_lflag 影响驱动程序和用户之间的接口(如回显打开或关闭、可视地擦除字符、允许终端产生的信号以及对后台输出的作业控制停止信号),c_cc 数组包含了所有可以更改的控制字符。另外,类型 tcflag_t 经常被定义为 unsigned int 或者 unsigned long,类型 cc_t 常被定义为 unsigned char。
下面的四个图列出了所有可以更改以影响终端设备特性的终端标志,其中的每个选项的详细说明见[url=http://aisxyz.iteye.com/admin/blogs/2422746]终端属性和选项标志[/url]一节。
[img]http://dl2.iteye.com/upload/attachment/0129/7801/7976b436-128c-3c6a-a4f3-7dfeaba4d5c7.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0129/7803/a8b4c7c9-9018-3541-a4c9-e0a69749d353.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0129/7805/574eaca8-98b5-3182-b60e-54477bf256f8.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0129/7807/f6e64eab-4c69-316f-9db7-2eebf4857bf0.png[/img]
要检测和更改终端设备的这些特性,可以使用下图列出的用来操作终端设备的各个函数。
[img]http://dl2.iteye.com/upload/attachment/0129/7809/a258820f-8e25-3c9a-bc73-9fe9594424f0.png[/img]
其中 tcgetpgrp、tcgetsid 和 tcsetpgrp 函数在[url=http://aisxyz.iteye.com/admin/blogs/2393509]进程组、会话和控制终端[/url]一节中已经说明,其它函数会在后面介绍。注意,Single UNIX Specification 没有对终端设备使用经典的 ioctl 函数(见[url=http://aisxyz.iteye.com/admin/blogs/2379283]终端I/O函数 ioctl[/url]一节),而是使用这些函数的原因是:对于终端设备的 ioctl 函数,其最后一个参数的数据类型随执行动作的不同而改变。因此,不可能对参数进行类型检查。这些函数之间的关系如下图所示。
[img]http://dl2.iteye.com/upload/attachment/0129/7811/80eab3ec-e536-3526-8266-9d8d093ff9ec.png[/img]
这些选项既可以在程序中使用 tcgetattr 和 tcsetattr 函数进行检查和更改,也可以在 shell 中用 stty(1) 命令进行检查和更改。stty(1)命令其实就相当于上表中的前 6 个函数的接口。使用“-a”选项,stty(1) 将显示终端的所有选项,如下图所示。
[img]http://dl2.iteye.com/upload/attachment/0129/8633/abc4239b-fbbc-3566-91e6-1e448c9c8830.png[/img]
其中,名字前有一个连字符的选项表示被禁用。最后 4 行显示了各终端特殊字符(见[url=http://aisxyz.iteye.com/admin/blogs/2422413]终端特殊输入字符[/url])的当前设置。
另外,stty 命令使用它的标准输入获得和设置终端的选项标志。这意味着如果希望了解名为 tty1a 的终端的设置,可以键入:
stty -a < /dev/tty1a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值