第五章 连接控制:学习stty
-
设备文件是链接,而不是容器。设备文件的i-节点存储的是指向内核子程序的指针,而不是文件的大小和存储列表。内核中传输设备数据的子程序被称为设备驱动程序。
2.read工作方式:内核首先找到文件描述符的i-节点,该i-节点用于告诉内核文件的
类型。如果文件是磁盘文件,那么内核通过访问块分配列表来读取数据。如果文件是设备文件,那么内核通过调用该设备驱动程序的read部分来读取数据。其他的操作例如open,write,lseek,close等都是类似的
一、磁盘连接的属性
1. 与磁盘文件的连接通常包含内核缓冲区,从进程到磁盘的字节先被缓冲,然后才从内核的缓冲区被发送出去。磁盘连接具有缓冲区这样一个属性。到终端的连接则不同,进程需要尽快把到终端的数据传送出去。
2.进程和磁盘文件之间的连接有若干属性,例如缓冲,自动添加模式等. 若O_SYNC位被置,则连接关闭缓冲,若O_APPEND若被置则把write和lseek组合为一个原子操作,每个对write的调用自动调用lseek将内容添加到文件的末尾。
3.可以通过修改控制变量改变文件描述符的动作,有三个步骤:
( 1 ) 从内核中读取设置到变量 (用fcntl())
( 2 ) 修改这些设置
( 3 ) 将设置返回内核
这三个步骤是Unix中读取和修改连接属性的典型方法
4.fcntl并不是仅有的用来设置文件描述符属性的方法。通常在打开一个文件时,应该知道需要怎样的设置。可以通过系统调用open的第二个参数的一部分来设置文件描述符的属性位。例如:
fd = open ( “filename”,O_WRONLY | O_APPEND | O_SYNC );
以写方式打开文件filename并将O_APPEND和O_SYNC位开启。open的第二个参数不只是读、写或者读/写的选择。
Open支持的其他标志位:
O_CREAT 如果不存在,创建该文件。可查看O_EXCL
O_TRUNC 如果文件存在,将文件长度置为0
O_EXCL 防止两个进程创建同样的文件。如果文件存在且O_EXCL被置位,则返回-1
磁盘连接小结
内核在磁盘和进程间传输数据。内核中进行这些传输的代码有很多选项。程序可使用open和fcntl系统调用控制这些数据传输的内部运作。
二、终端连接的属性
1.处理进程和外部设备间数据流的内核子程序的集合被称为终端驱动程序或者tty驱动程序,驱动程序包含很多控制设备操作的设置。进程可以读、修改和重置这些设置
2.stty命令让用户读取和修改终端驱动程序的设置
3.tty驱动程序包含很多对传入的数据所进行的操作。分为四种:
输入:驱动程序如何处理从终端来的字符
输出:驱动程序如何处理流向终端的字符
控制:字符如何被表示--位的个数、位的奇偶性、停止位等
本地:驱动程序如何处理来自驱动程序内部的字符
输入处理包括:将小写字母转换为大写字母,去除最高位及将回车符转换为换行符。 输出处理包括:用若干个空格符代替制表符,将换行符转换为回车符及将小写字母转换为大写字母
控制设置包括:奇偶性及停止位的个数。
本地处理包括:回显字符给用户及缓冲输入直到用户按回车键。
4.改变终端驱动程序的设置就像改变磁盘文件连接的设置一样:
-
从驱动程序获得属性
-
修改所要修改的属性
-
将修改后的属性送回驱动程序
5.库函数tcgetattr和tcsetattr提供对终端驱动程序的访问。两个函数在termios结构中交换设置:
tcgetattr | |
目标: | 读取tty驱动程序的属性 |
头文件: | #include,<termios.h> |
函数原型: | int reslut = tcgetattr( int fd, struct termios *info); |
参数: | fd 与终端相联的文件描述符 info 指向终端结构的指针 |
返回值: | -1 遇到错误 0 成功返回 |
tcgetattr从文件fd相关的终端驱动程序中获取当前设置,并把它复制到info指针所指的结构中。
tcsetattr | |
目标: | 设置tty驱动程序的属性 |
头文件: | #include <termios.h> |
函数原型: | int reslut = tcsetattr( int fd, int when, struct termios *info ); |
参数: | fd 与终端相联的文件描述符 when 改变设置的时间 info 指向终端结构的指针 |
返回值: | -1 遇到错误 0 成功返回 |
tcsetattr从info所指的结构中将驱动程序的设置复制到与文件fd相关的终端驱动程序中。when参数告诉tcsetattr在什么时候更新驱动程序设置。When的允许值如下所示:
(1)TCSANOW 立即更新驱动程序设置
(2)TCSADRAIN 等待直到驱动程序队列中的所有输出都被传送到终端。
(3)TCSAFLUSH 等待直到驱动程序队列中的所有输出都被传送出去。然后释放队列中的输入数据,并进行一定的变化
6.termios结构包含若干标志集和一个控制字符的数组(c_cc)。含有特殊功能的键都被存储在这个数组中。数组中的每个位置都由termios.h中的常量定义。例如,attribs.c_cc[VERASE] = '/b' 告诉驱动程序将退格键作为删除键。
7.每个属性在标志集中都占有一位。属性的掩码定义在termios.h中。要测试一个属性,需要将标志集与那个位的掩码相与。要启动这个属性,将该位开启。要禁止这个属性,将该位关闭。上面的情况如下所示:
操作 代码 |
测试位 if( flagset & MASK ) ... |
置位 flagset | = MASK |
清除位 flagset &= ~MASK |
8.到磁盘文件的连接有一个属性集,到终端的连接有另外一个属性集。那么到其他类型设备的连接是怎样的?其他类型的设备也有各自的属性集,如扫描仪解析度,颜色深度等。可以利用系统调ioctl查看和控制一个设备的设置。