From b6d51dc40eb420d81a28c3b3c7b6de4ee9319dfc Mon Sep 17 00:00:00 2001 From: "Joshua M. Clulow" Date: Fri, 2 Jul 2021 12:06:18 -0700 Subject: [PATCH] illumos,tty: UV_TTY_MODE_IO waits for 4 bytes uv_tty_set_mode() allows a tty device to be set to raw mode with UV_TTY_MODE_RAW, which correctly sets MIN and TIME to appropriate values for character input. When UV_TTY_MODE_IO is passed, on illumos systems a compatibility implementation of cfmakeraw() is used that does _not_ set MIN or TIME. As a result, consumers of IO mode will block until a minimum of 4 bytes is available on the tty instead of just 1 as is expected. PR-URL: https://github.com/libuv/libuv/pull/3219 Reviewed-By: Jameson Nash --- src/unix/tty.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/unix/tty.c b/src/unix/tty.c index 6f60abaa..9442cf16 100644 --- a/src/unix/tty.c +++ b/src/unix/tty.c @@ -242,6 +242,24 @@ static void uv__tty_make_raw(struct termios* tio) { tio->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); tio->c_cflag &= ~(CSIZE | PARENB); tio->c_cflag |= CS8; + + /* + * By default, most software expects a pending read to block until at + * least one byte becomes available. As per termio(7I), this requires + * setting the MIN and TIME parameters appropriately. + * + * As a somewhat unfortunate artifact of history, the MIN and TIME slots + * in the control character array overlap with the EOF and EOL slots used + * for canonical mode processing. Because the EOF character needs to be + * the ASCII EOT value (aka Control-D), it has the byte value 4. When + * switching to raw mode, this is interpreted as a MIN value of 4; i.e., + * reads will block until at least four bytes have been input. + * + * Other platforms with a distinct MIN slot like Linux and FreeBSD appear + * to default to a MIN value of 1, so we'll force that value here: + */ + tio->c_cc[VMIN] = 1; + tio->c_cc[VTIME] = 0; #else cfmakeraw(tio); #endif /* #ifdef __sun */