终端I/O
一、综述
终端I/O有两种不同的工作模式:
-
规范模式输入处理。在这种模式中,对终端输入以行为单位进行处理。对于每个读请求,终端驱动程序最多返回一行。
-
非规范模式输入处理。输入字符不装配成行。
POSIX.1定义了11个特殊字符,其中9个可以更改。例如文件结束符(Ctrl+D)和挂起字符(Ctrl+Z)。
终端设备是由通常位于内核中的终端驱动程序控制的。每个终端设备都有一个输入队列和一个输出队列,如下图所示:
许多UNIX系统在一个称为终端行规程的模块 中进行全部的规范处理。可以将这个模块设想成一个盒子,位于内核通用读、 写函数和实际设备驱动程序之间,如下图所示:
终端设备特性包含在头文件为<termios.h>
如下结构中:
struct termios{
tcflag_t c_iflag;
tcflag_t c_oflag;
tcflag_t c_cflag;
tcflag_t c_lflag;
cc_t c_cc[NCCS];
}
//c_cc数组包含了所有可以更改的特殊字符,NCCS是该数组中元素的数量(15~20)
//cc_t类型的长度足以保存每个特殊字符,典型的是unsigned char。
//类型tcflag_t的长度足以保存每个标志值,它经常被定义为unsigned int或者 unsigned long。
输入标志通过终端设备驱动程序控制字符的输入,输出标志则控制驱动程序输出,控制标志影响RS-232串行线,本地标志影响驱动程序和用户之间的接口。
更改影响终端设备特性的标志如下所示:
对终端设备进行操作的各个函数:
函数关系示意图:
二、特殊输入字符
POSIX.1定义了11个在输入时要特殊处理的字符,如下图所示:
-
9个字符的值可以任意更改。
-
不能更改的两个特殊字符是换行符和回车符(分别是\n和\r),也可能是STOP和 START字符(依赖于实现)。
-
更改只需要修改
termios
结构中c_cc
数组的相应项。该数组中的元素都用名字作为下标进行引用,每个名字都以字母V 开头。 -
禁止使用这些字符,只虚将
c_cc
数组中的某项设置为_POSIX_VDISABLE
的值,则禁止使用相应特殊字符。
三、获得和设置终端属性
获得和设置termios
结构,调用tcgetattr和tcsetattr
函数,可以 检测和修改各种终端选项标志和特殊字符,使终端按我们所希望的方式进行操作。
#include <termios.h>
int tcgetattr(int fd, struct termios *termptr);
int tcsetattr(int fd, int opt, const struct