终端属性和选项标志
程序员文章站
2022-07-01 09:17:12
...
tcgetattr 和 tcsetattr 函数可以分别获取和设置 termios 结构,这样就可以检测和修改各种终端选项标志和特殊字符。
其中指向 termios 结构的指针参数 termptr 或者返回当前终端的属性,或者设置该终端的属性。这两个函数只对终端设备进行操作,若 fd 参数没有引用终端设备,则出错返回 -1,并将 errno 设置为 ENOTTY。
tcsetattr 的参数 opt 可以指定新的终端属性何时起作用。它支持以下几个常量。
* TCSANOW:更改立即发生。
* TCSADRAIN:发送了所有输出后更改才发生。若更改输出参数则应使用此选项。
* TCSAFLUSH:发送了所有输出后更改才发生。更进一步,在更改发生时未读的所有输入数据都被丢弃(冲洗)。
注意,tcsetattr 函数即使未能执行所有要求的动作也会返回 OK,这意味着在调用该函数设置所希望的属性后,需调用 tcgetattr 来检测实际的终端属性与所希望的属性是否有区别。
终端第一次被打开时的属性视具体情况而定。一些系统可能会初始化为具体实现所定义的值,另一些可能会保留并使用最后一次使用终端时的属性值。通过打开一个带有 O_TTY_INIT(见不带缓冲的文件I/O之open)标志的驱动设备,可以确认终端的行为是否遵循标准,这样就能在调用 tcgetattr 时确保初始化 termios 结构中的任何非标准部分,使得在获取和修改终端属性时,终端的表现符合预期。
在终端 I/O 综述一节列出了影响终端的选项标志,其中所有的选项标志(除所谓的屏蔽字标志外)都用一位或多位(设置或清除)表示。屏蔽字标志定义多个位,它们组合在一起,可以定义一组值。屏蔽字标志有一个定义名,每个值也有一个名字。例如,为了设置字符长度,首先用字符长度屏蔽字标志 CSIZE 将表示字符长度的位清 0,然后设置这几个值之一:CS5、CS6、CS7、CS8。
由 Linux 和 Solaris 支持的 6 个延迟值也有屏蔽字标志:BSDLY、CRDLY、FFDLY、NLDLY、TABDLY 和 VTADLY。在所有情况下,延迟屏蔽字为 0 就表示没有延迟。如果指定了延迟,则由 OFILL 和 OFDEL 标志决定是由驱动器进行实际延迟还是只传输填充字符。
下面这个程序演示了如何使用这些屏蔽字标志取一个值或者设置一个值。
下面是按字母顺序对终端 I/O 综述中列出的所有终端选项标志的详细说明,同时也指出了它们所属的终端标志字段以及支持的平台。
#include <termios.h> int tcgetattr(int fd, struct termios *termptr); int tcsetattr(int fd, int opt, const struct termios *termptr); /* 两个函数的返回值:若成功,返回 0;否则,返回 -1 */
其中指向 termios 结构的指针参数 termptr 或者返回当前终端的属性,或者设置该终端的属性。这两个函数只对终端设备进行操作,若 fd 参数没有引用终端设备,则出错返回 -1,并将 errno 设置为 ENOTTY。
tcsetattr 的参数 opt 可以指定新的终端属性何时起作用。它支持以下几个常量。
* TCSANOW:更改立即发生。
* TCSADRAIN:发送了所有输出后更改才发生。若更改输出参数则应使用此选项。
* TCSAFLUSH:发送了所有输出后更改才发生。更进一步,在更改发生时未读的所有输入数据都被丢弃(冲洗)。
注意,tcsetattr 函数即使未能执行所有要求的动作也会返回 OK,这意味着在调用该函数设置所希望的属性后,需调用 tcgetattr 来检测实际的终端属性与所希望的属性是否有区别。
终端第一次被打开时的属性视具体情况而定。一些系统可能会初始化为具体实现所定义的值,另一些可能会保留并使用最后一次使用终端时的属性值。通过打开一个带有 O_TTY_INIT(见不带缓冲的文件I/O之open)标志的驱动设备,可以确认终端的行为是否遵循标准,这样就能在调用 tcgetattr 时确保初始化 termios 结构中的任何非标准部分,使得在获取和修改终端属性时,终端的表现符合预期。
在终端 I/O 综述一节列出了影响终端的选项标志,其中所有的选项标志(除所谓的屏蔽字标志外)都用一位或多位(设置或清除)表示。屏蔽字标志定义多个位,它们组合在一起,可以定义一组值。屏蔽字标志有一个定义名,每个值也有一个名字。例如,为了设置字符长度,首先用字符长度屏蔽字标志 CSIZE 将表示字符长度的位清 0,然后设置这几个值之一:CS5、CS6、CS7、CS8。
由 Linux 和 Solaris 支持的 6 个延迟值也有屏蔽字标志:BSDLY、CRDLY、FFDLY、NLDLY、TABDLY 和 VTADLY。在所有情况下,延迟屏蔽字为 0 就表示没有延迟。如果指定了延迟,则由 OFILL 和 OFDEL 标志决定是由驱动器进行实际延迟还是只传输填充字符。
下面这个程序演示了如何使用这些屏蔽字标志取一个值或者设置一个值。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <termios.h> int main(void){ struct termios term; if(tcgetattr(STDIN_FILENO, &term) < 0){ printf("tcgetattr error\n"); exit(1); } switch(term.c_cflag & CSIZE){ case CS5: printf("5 bits/byte\n"); break; case CS6: printf("6 bits/byte\n"); break; case CS7: printf("7 bits/byte\n"); break; case CS8: printf("8 bits/byte\n"); break; default: printf("unknown bits/byte\n"); } term.c_cflag &= ~CSIZE; // zero out the bits term.c_cflag |= CS8; // set 8 bits/byte if(tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0){ printf("tcsetattr error\n"); exit(1); } exit(0); }
下面是按字母顺序对终端 I/O 综述中列出的所有终端选项标志的详细说明,同时也指出了它们所属的终端标志字段以及支持的平台。
下一篇: 为Linux系统的服务器设置防火墙的方法