summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/main.rs1
-rw-r--r--cli/util/unix.rs24
-rw-r--r--runtime/ops/tty.rs35
3 files changed, 35 insertions, 25 deletions
diff --git a/cli/main.rs b/cli/main.rs
index c6249a21f..80fe59005 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 2fa3c2063..fd0c94ea6 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::<termios>();
- if tcgetattr(libc::STDIN_FILENO, &mut termios) == 0 {
- static mut ORIG_TERMIOS: Option<termios> = 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 bf85c757e..477af9741 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<Option<termios>> = OnceCell::new();
+ ORIG_TERMIOS.get_or_init(|| {
+ let mut termios = std::mem::zeroed::<termios>();
+ 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::<TtyModeStore>().clone();
let previous_mode = tty_mode_store.get(rid);