diff --git a/src/lib.rs b/src/lib.rs index 3dd8d4ec5b..52a8d90b7b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,6 +86,30 @@ pub fn spawn_shell(user: &User) -> IoResult { } } + // The login name is read with the `liner` line editor, which switches the + // console pty into raw mode (ICANON/ECHO cleared) and does not restore it. + // In raw mode the pty's line discipline never flushes a completed line to + // the slave's read buffer the way a shell's canonical `read_line` expects, + // so the interactive shell can never receive a typed command. Reset the + // terminal to sane canonical/cooked settings before exec'ing the shell. + #[cfg(target_os = "redox")] + unsafe { + let mut t: libc::termios = core::mem::zeroed(); + if libc::tcgetattr(0, &mut t) == 0 { + t.c_iflag |= (libc::ICRNL | libc::IXON) as _; + t.c_oflag |= (libc::OPOST | libc::ONLCR) as _; + t.c_lflag |= (libc::ICANON + | libc::ECHO + | libc::ECHOE + | libc::ECHOK + | libc::ISIG + | libc::IEXTEN) as _; + t.c_cc[libc::VMIN] = 1; + t.c_cc[libc::VTIME] = 0; + let _ = libc::tcsetattr(0, libc::TCSANOW, &t); + } + } + let mut command = user.shell_cmd(); let mut child = command.spawn()?;