I'm writing a VT100 terminal engine but input handling is somehow tricky. First I initialize my tty with no echoing.
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");
}
Next I initialize a non-blocking keyboard file descriptor.
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");
}
So far so good. The main loop is just polling events and will break if pressing ESC.
int main() {
while (true) {
read(kfd, evt, sizeof(input_event));
if (evt->type == EV_KEY && evt->value == 1 && evt->code == KEY_ESC)
break;
}
}
So I type some characters. Meanwhile my terminal is buffering all characters that I am typing in. After the program exits all characters got displayed.
So here my question: How can I disable terminal output stream buffering while my program is running?
Here is a GIF to illustrate the problem.
Steps:
- sudo ./clac
- engine is running but not echoing; typing some characters
- pressing ESC
- typed in characters got displayed; program exit