问题
How do I enter raw or cbreak mode under WSL? I want keyboard input available to stdin immediately, instead of waiting for enter key.
I've tried using termios to put the TTY in raw or canonical mode, either by using cfmakeraw
or by fiddling with various flags, following the example from the termios manual page and several variations (only disabling ICANON
, code similar to ncurses internals, and so on):
termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
| INLCR | IGNCR | ICRNL | IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
termios_p->c_cflag &= ~(CSIZE | PARENB);
termios_p->c_cflag |= CS8;
I'm setting VMIN
to 1 and VTIME
to 0, and also using fcntl
to allow reading from stdin without blocking when no data's in the buffer (fcntl(0, F_SETFL, O_NONBLOCK)
, which seems to work properly).
Aside from this, I've also tried simply shell-executing stty cbreak
and stty raw
. These kinds of things work on a Debian machine, but do not work on Debian running under WSL -- my keypresses don't show up when reading from stdin.
Specifically there are two problems: if ICRNL
is not disabled, and I hit a key and then hit enter quickly enough, the key will be read on stdin. But 1) enter should not be needed in raw or cbreak mode, and 2) if anything is written to stdout before input is read, anything in the buffer will disappear before it's read.
Is this a bug with WSL's console, or some platform-specific behavior that needs a workaround?
来源:https://stackoverflow.com/questions/56289226/leaving-canonical-mode-entering-raw-cbreak-mode-in-wsl