我正在编写一个 VT100 终端引擎,但输入处理有点棘手。首先,我初始化我的 tty,没有回显。
static void init_tty() {
if (tcgetattr(STDIN_FILENO, &ctty) != 0)
throw std::runtime_error("can not get tty attribute");
ctty.c_lflag &= ~(FLAG(ICANON) | FLAG(ECHO) | FLAG(ISIG));
if (tcsetattr(STDIN_FILENO, TCSANOW, &ctty) != 0)
throw std::runtime_error("can not set tty attribute");
}
接下来我初始化一个非阻塞键盘文件描述符。
static void init_keyboard(const char *device) {
if ((kfd = open(device, FLAG(O_RDONLY) | FLAG(O_SYNC))) == -1)
throw std::runtime_error("can not open keyboard fd");
unsigned flags = fcntl(kfd, F_GETFL, 0);
flags |= FLAG(O_NONBLOCK);
if (fcntl(kfd, F_SETFL, flags) == -1)
throw std::runtime_error("can not set keyboard fd flags");
}
到目前为止,一切都很好。主循环只是轮询事件,如果按 ESC 会中断。
int main() {
while (true) {
read(kfd, evt, sizeof(input_event));
if (evt->type == EV_KEY && evt->value == 1 && evt->code == KEY_ESC)
break;
}
}
所以我输入了一些字符。同时,我的终端正在缓冲我输入的所有字符。程序退出后,所有字符都会显示出来。
所以我的问题是:如何在程序运行时禁用终端输出流缓冲?
这是一个 GIF 来说明这个问题。
脚步:
- 须藤 ./clac
- 引擎正在运行但没有回声;输入一些字符
- 按 ESC
- 输入的字符得到显示;程序退出