diff --git a/cli/main.rs b/cli/main.rs index c6249a21f1..80fe59005f 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -323,7 +323,6 @@ pub(crate) fn unstable_warn_cb(feature: &str) { pub fn main() { setup_panic_hook(); - util::unix::prepare_stdio(); util::unix::raise_fd_limit(); util::windows::ensure_stdio_open(); #[cfg(windows)] diff --git a/cli/util/unix.rs b/cli/util/unix.rs index 2fa3c20636..fd0c94ea68 100644 --- a/cli/util/unix.rs +++ b/cli/util/unix.rs @@ -43,27 +43,3 @@ pub fn raise_fd_limit() { } } } - -pub fn prepare_stdio() { - #[cfg(unix)] - // SAFETY: Save current state of stdio and restore it when we exit. - unsafe { - use libc::atexit; - use libc::tcgetattr; - use libc::tcsetattr; - use libc::termios; - - let mut termios = std::mem::zeroed::(); - if tcgetattr(libc::STDIN_FILENO, &mut termios) == 0 { - static mut ORIG_TERMIOS: Option = None; - ORIG_TERMIOS = Some(termios); - - extern "C" fn reset_stdio() { - // SAFETY: Reset the stdio state. - unsafe { tcsetattr(libc::STDIN_FILENO, 0, &ORIG_TERMIOS.unwrap()) }; - } - - atexit(reset_stdio); - } - } -} diff --git a/runtime/ops/tty.rs b/runtime/ops/tty.rs index bf85c757e9..477af9741e 100644 --- a/runtime/ops/tty.rs +++ b/runtime/ops/tty.rs @@ -118,6 +118,41 @@ fn op_stdin_set_raw( } #[cfg(unix)] { + fn prepare_stdio() { + // SAFETY: Save current state of stdio and restore it when we exit. + unsafe { + use libc::atexit; + use libc::tcgetattr; + use libc::tcsetattr; + use libc::termios; + use once_cell::sync::OnceCell; + + // Only save original state once. + static ORIG_TERMIOS: OnceCell> = OnceCell::new(); + ORIG_TERMIOS.get_or_init(|| { + let mut termios = std::mem::zeroed::(); + if tcgetattr(libc::STDIN_FILENO, &mut termios) == 0 { + extern "C" fn reset_stdio() { + // SAFETY: Reset the stdio state. + unsafe { + tcsetattr( + libc::STDIN_FILENO, + 0, + &ORIG_TERMIOS.get().unwrap().unwrap(), + ) + }; + } + + atexit(reset_stdio); + return Some(termios); + } + + None + }); + } + } + + prepare_stdio(); let tty_mode_store = state.borrow::().clone(); let previous_mode = tty_mode_store.get(rid);