我试图了解终端 I/O 的工作原理。
当终端像这样置于非规范模式时(缺少错误处理):
struct termios term_original, term_current;
tcgetattr(STDIN_FILENO, &term_original);
term_current = term_original;
term_current.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO);
term_current.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | INPCK | ISTRIP | IXON | PARMRK);
term_current.c_oflag &= ~(OPOST);
term_current.c_cc[VMIN] = 1;
term_current.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSADRAIN, &term_current);
一个简单的读取循环可以读取每次按下按钮生成的数据,如下所示:
char c;
while (read(0, &c, 1) != -1) { PRINT_CHAR(c); }
现在,
- 在我的键盘上按 Esc 会生成:0x1b。
- 按 F1 生成:0x1b 0x4f 0x50。
- 按 F5 生成:0x1b 0x5b 0x31 0x35 0x7e。
在读取和处理这个输入方面,如何确定一个按钮按下的输出在哪里结束,下一个按钮从哪里开始?我找不到可辨别的模式,而且 Esc 生成的单字节也与大多数多字节生成按钮按下的输出的第一个字节相同,这一事实似乎表明没有。是否有其他机制来确定按钮边界的位置?