VT100原始模式下终端输出随机异常问题排查与解决
终端原始模式切换后随机异常输出的解决
问题现象
一段切换至VT100原始模式的C++代码,使用g++ main.cc编译运行后,约80%场景输出符合预期:
test test test
但会随机出现各类异常输出,例如:
空行过多的情况:
test test test
或者缩进偏移的情况:
test test test
甚至还会出现大写输出等异常。该问题在gnome-terminal与xterm终端中均存在,尝试在不同位置调用fflush、tcflush、tcdrain均无法解决,仅使用gcc -Og main.cc编译生成的代码能正常运行。
问题根源
未对termios结构体进行初始化。未初始化的结构体成员会保留栈上的随机内存值,调用tcsetattr时这些随机值会被应用到终端属性中,导致终端行为出现不可预测的异常。
修正后的代码
通过对termios结构体进行零初始化,即可解决该问题:
#include<cstdio> extern"C"{ #include<termios.h> #include<unistd.h> } int main(){ termios termattr_bak; termios termattr{}; // 关键:对结构体进行零初始化 /* 切换至原始模式*/ tcgetattr(STDIN_FILENO,&termattr_bak); termattr.c_iflag |= IGNBRK; termattr.c_iflag &= ~unsigned(INLCR|ICRNL|IXON|IXOFF); termattr.c_lflag &= ~unsigned(ICANON|ECHO|ECHOK|ECHOE|ECHONL|ISIG|IEXTEN); termattr.c_cc[VMIN] = 1; termattr.c_cc[VTIME] = 0; tcsetattr(STDIN_FILENO,TCSAFLUSH,&termattr); /* */ printf("test\r\n"); printf("test\r\n"); printf("test\r\n"); fflush(stdout); /* 恢复终端属性*/ tcsetattr(STDIN_FILENO,TCSAFLUSH,&termattr_bak); return 0; }
内容的提问来源于stack exchange,提问作者kmft3kte
相关产品推荐
相关产品推荐

