tcgetattr函数和tcsetattr函数----终端控制介绍与使用
1. tcgetattr函数
头文件:#include <termios.h>
函数原型:int tcgetattr(int fd, struct termios *termios_p);
说明:tcgetattr函数用于获取与终端相关的参数。参数fd为终端的文件描述符,返回的结果保存在termios结构体中,该结构体一般包括如下的成员:
其具体意义如下:
c_iflag: 输入模式标志,控制终端输入方式,具体参数如下表所示:
键值 | 说明 | 键值 | 说明 |
IGNBPK | 忽略BREAK键输入 | BRKINT | 如果设置了IGNBPK,忽略BREAK键输入 |
IGNPAR | 忽略奇偶校验错误 | INLCR | 将输入的NL(换行)转换成CR(回车) |
PARMRK | 标识奇偶校验错误 | ICRNL | 将输入的回车转化成换行(如果IGNCR未设置的情况下) |
INPCK | 允许输入奇偶校验 | IUCLC | 将输入的大写字符转换成小写字符(非POSIX) |
ISTRIP | 去除字符的第8个比特 | IXON | 允许输出时对XON/XOFF流进行控制 |
IGNCR | 忽略输入的回车 | IXANY | 输入任何字符将重启停止的输出 |
IMAXBEL | 当输入队列满的时候开始响铃 | IXOFF | 允许输入时对XON/XOFF流进行控制 |
c_oflag: 输出模式标志,控制终端输出方式,具体参数如下表所示:
键值 | 说明 | 键值 | 说明 |
OPOST | 处理后输出 | OLCUC | 将输得小写字符转换成大写字符 |
ONOCR | 第一行不输出回车符 | ONLCR | 将输出的NL(换行)转换成CR(回车)及NL(换行) |
ONLRET | 不输出回车符 | OCRNL | 将输出的CR(回车)转换成NL(换行) |
OFILL | 发送填充字符以延迟终端输出 | OFDEL | 以ASCII码的DEL作为填充字符,如果为设置该参数,填充字符为NULL |
BSDLY | 空格输出延迟,可以取BSO或BS1 | NLDLY | 换行输出延迟,可以取NL0(不延迟)或NL0(延迟0.1s) |
VTDLY | 垂直制表符输出延迟,可以取VT0或VT1 | CRDLY | 回车延迟,取值范围为:CR0、CR1、CR2和CR3 |
FFDLY | 换页延迟,可以取FF0或FF1 | TABDLY | 水平制表符输出延迟,取值范围为TAB0、TAB1、TAB2和TAB3 |
c_cflag: 控制模式标志,指定终端硬件控制信息,具体参数如下表所示:
键值 | 说明 | 键值 | 说明 |
CSTOPB | 设置两个停止位 | CBAUD | 波特率(4+1位)(非POSIX) |
CREAD | 使用接收器 | CBAUDEX | 附加波特率(1位)(非POSIX) |
PARODD | 使用奇偶校验 | CSIZE | 字符长度,取值范围为CS5、CS6、CS7或CS8 |
HUPCL | 关闭设备时挂起 | PARODD | 对输入使用奇偶校验,对输出是用偶校验 |
CRTSCTS | 使用RTS/CTS流控制 | CLOCAL | 忽略调制解调器线路状态 |
c_lflag: 本地模式标志,控制终端编辑功能,具体参数如下表所示:
键值 | 说明 | 键值 | 说明 |
ICANON | 使用标准输入模式 | ISIG | 当输入INTR、OUIT、SUSP时,产生响应的信号 |
ECHO | 显示输入字符 | XCASE | 在ICANON和XCASE同时设置的情况下,终端只使用大写 |
TOSSTOP | 向后台输出发送SIGTTOU信号 | ECHOE | 如果ICANON同时设置,ERASE将删除输入的字符 |
ECHOK | 如果ICANON同时设置,KILL将删除当前行 | ||
ECHONL | 如果ICANON同时设置,即使ECHO没有设置依然显示换行符 | ||
ECHOPRT | 如果ECHO和ICANON同时设置,将删除打印出的字符(非POSIX) |
c_cc[NCCS]: 控制字符,用于保存终端驱动程序中的特殊字符,如输入结束符等。c_cc中定义了如下表所示的控制字符:
宏 | 说明 | 宏 | 说明 |
VINTR | interrupt字符 | VEOL | 附加的end-of-file字符 |
VQUIT | quit字符 | VTIME | 非规范模式读取时的超时时间 |
VERASE | erase字符 | VSTOP | stop字符 |
VKILL | kill字符 | VSTART | start字符 |
VEOF | end-of-file字符 | VSUSP | suspend字符 |
VMIN | 非规范模式读取时的最小字符数 |
2. tcsetattr函数
头文件:#include<termios.h>
函数原型:int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
说明:tcsetattr函数用于设置终端参数。函数在成功的时候返回0,失败的时候返回-1,并设置errno的值。参数fd为打开的终端文件描述符,参数optional_actions用于控制修改起作用的时间,而结构体termios_p中保存了要修改的参数。optional_actions可以取如下的值:
TCSANOW:不等数据传输完毕就立即改变属性。
TCSADRAIN:等待所有数据传输结束才改变属性。
TCSAFLUSH:等待所有数据传输结束,清空输入输出缓冲区才改变属性。
错误信息:
EBADF:非法的文件描述符。
EINTR:tcsetattr函数调用被信号中断。
EINVAL:参数optional_actions使用了非法值,或参数termios中使用了非法值。
ENOTTY:非终端的文件描述符。
范例:
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
int main(void){
//term用于存储获得的终端参数信息
struct termios term;
int err;
//获得标准输入的终端参数,将获得的信息保存在term变量中
if(tcgetattr(STDIN_FILENO,&term)==-1){
perror("Cannot get standard input description");
return 1;
}
//修改获得的终端信息的结束控制字符
term.c_cc[VEOF]=(cc_t)0x07;
//使用tcsetattr函数将修改后的终端参数设置到标准输入中
//err用于保存函数调用后的结果
err=tcsetattr(STDIN_FILENO,TCSAFLUSH,&term);
//如果err为-1或是出现EINTR错误(函数执行被信号中断),
//给出相关出错信息
if(err==-1 && err==EINTR){
perror("Failed to change EOF character");
return 1;
}
return 0;
}
用gcc编译程序,得到可执行程序。在执行程序前,按“Ctrl+D”可以使终端结束。执行程序后,按“Ctrl+D”失去了作用,而输入“Ctrl+G”实现了原来“Ctrl+D”的功能。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!