用termios.h模拟ncurses raw():cfmakeraw参数及终端信号疑问
关于termios.h与cfmakeraw()的终端配置疑问解答
1. 禁用终端信号(如CTRL-C不终止程序)的关键标志
负责实现这一功能的是**ISIG标志**,它属于termios结构的c_lflag字段。
当ISIG被设置时,终端会将INTR(CTRL-C)、QUIT(CTRL-\)等特殊字符转换为对应的信号发送给进程;而cfmakeraw()的配置中,已经通过termios_p->c_lflag &= ~ISIG清除了这个标志——此时这些特殊输入会被当作普通字符读取,不会触发程序终止等信号行为。
2. cfmakeraw()不设置VMIN和VTIME的原因
VMIN(c_cc[VMIN])和VTIME(c_cc[VTIME])是非规范模式下的读取行为控制参数,不同场景的需求差异极大:
VMIN=0, VTIME=0:非阻塞读取,有数据就返回,无数据直接返回0VMIN=1, VTIME=0:阻塞等待至少1个字符输入VMIN=0, VTIME=5:超时等待5秒,期间有数据就返回,超时无数据返回0VMIN=3, VTIME=5:等待3个字符,或5秒超时(先满足哪个条件就触发返回)
cfmakeraw()的设计目标是提供raw模式的核心终端属性设置,而把读取行为的选择权交给开发者,根据自身程序的需求来配置这两个参数,因此不做默认设置。
3. 复刻ncurses raw()的完整配置建议
如果你想完整复刻ncurses的raw()效果,在你现有代码的基础上,需要补充以下配置:
struct termios x; // 先保存原终端属性,方便后续恢复 tcgetattr(STDIN_FILENO, &x); // 输入标志:禁用特殊输入处理、流控制等 x.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); // 输出标志:禁用输出特殊处理 x.c_oflag &= ~OPOST; // 本地标志:禁用回显、规范模式、信号触发、扩展输入处理、换行回显 x.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); // 控制标志:设置8位字符,禁用奇偶校验 x.c_cflag &= ~(CSIZE | PARENB); x.c_cflag |= CS8; // 非阻塞读取配置(可根据需求调整) x.c_cc[VMIN] = 0; x.c_cc[VTIME] = 0; // 应用配置 tcsetattr(STDIN_FILENO, TCSANOW, &x);
不需要额外设置的参数:
- 所有被清除的标志对应的默认设置已经被覆盖,无需再调整
- 若没有特殊需求,
c_cc数组中除VMIN和VTIME外的其他参数(如VINTR、VQUIT等)在禁用ISIG后不再生效,无需修改
内容的提问来源于stack exchange,提问作者iloveclang
相关产品推荐
相关产品推荐

