Linux环境下如何将Ctrl+C作为输入读取,除signal外有哪些实现方案?
Linux环境下不使用
signal机制捕获Ctrl+C的实现方案 完全可以实现将Ctrl+C作为普通输入放入缓冲区读取,不需要依赖signal信号机制,核心实现方式是修改终端的termios配置:
实现原理
终端默认开启ISIG控制标志,当检测到Ctrl+C输入(对应ASCII码为0x03的ETX字符)时,会自动向前台进程组发送SIGINT信号,不会将该字符放入输入缓冲区。只要关闭该标志,终端就会跳过信号触发逻辑,直接把Ctrl+C对应的字符写入输入缓冲区,供程序直接读取。
具体实现步骤
- 调用
tcgetattr()获取当前终端的属性配置,保存原始配置用于程序退出前恢复 - 清空终端属性
c_lflag字段的ISIG位,按需也可同时清空ICANON位关闭行缓冲模式,实现输入字符即时读取不需要等待回车 - 调用
tcsetattr()将修改后的属性配置生效 - 程序退出前必须调用
tcsetattr()恢复原始终端属性,避免终端行为异常
最简C语言示例代码
#include <stdio.h> #include <termios.h> #include <unistd.h> int main() { struct termios old_attr, new_attr; // 获取当前终端属性 tcgetattr(STDIN_FILENO, &old_attr); new_attr = old_attr; // 关闭ISIG标志,关闭ICANON行缓冲 new_attr.c_lflag &= ~(ISIG | ICANON); // 配置立即生效 tcsetattr(STDIN_FILENO, TCSANOW, &new_attr); char c; while (1) { read(STDIN_FILENO, &c, 1); if (c == 0x03) { // 读到Ctrl+C printf("捕获到Ctrl+C输入\n"); break; } printf("读到普通字符: %c\n", c); } // 恢复原始终端属性 tcsetattr(STDIN_FILENO, TCSANOW, &old_attr); return 0; }
其他可选实现方式
除了修改termios属性外,也可以通过ioctl系统调用直接配置终端参数,不过termios是POSIX标准定义的通用接口,跨Linux、Unix系列系统的兼容性更好。
内容的提问来源于stack exchange,提问作者user16823964
相关产品推荐
相关产品推荐

