diff --git a/src/unix/solarish/compat.rs b/src/unix/solarish/compat.rs index a33645211ce37381d5891e024f8605aab359a33e..610dd109735a6fc700cded355190e5f927bc3908 100644 --- a/src/unix/solarish/compat.rs +++ b/src/unix/solarish/compat.rs @@ -4,8 +4,7 @@ use unix::solarish::*; pub unsafe fn cfmakeraw(termios: *mut ::termios) { - let mut t = *termios as ::termios; - t.c_iflag &= !(IMAXBEL + (*termios).c_iflag &= !(IMAXBEL | IGNBRK | BRKINT | PARMRK @@ -14,10 +13,26 @@ pub unsafe fn cfmakeraw(termios: *mut ::termios) { | IGNCR | ICRNL | IXON); - t.c_oflag &= !OPOST; - t.c_lflag &= !(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - t.c_cflag &= !(CSIZE | PARENB); - t.c_cflag |= CS8; + (*termios).c_oflag &= !OPOST; + (*termios).c_lflag &= !(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + (*termios).c_cflag &= !(CSIZE | PARENB); + (*termios).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 artefact 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: + (*termios).c_cc[VMIN] = 1; + (*termios).c_cc[VTIME] = 0; } pub unsafe fn cfsetspeed(