diff --git a/src/builtins/fg.rs b/src/builtins/fg.rs
index e135a088f..2ab762368 100644
--- a/src/builtins/fg.rs
+++ b/src/builtins/fg.rs
@@ -6,7 +6,9 @@
use crate::tokenizer::tok_command;
use crate::wutil::perror;
use crate::{env::EnvMode, tty_handoff::TtyHandoff};
-use libc::{STDIN_FILENO, TCSADRAIN};
+use libc::STDIN_FILENO;
+use nix::sys::termios;
+use std::os::fd::BorrowedFd;
use super::prelude::*;
@@ -142,9 +144,14 @@ pub fn fg(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) -> Built
}
let tmodes = job_group.tmodes.borrow();
if job_group.wants_terminal() && tmodes.is_some() {
- let termios = tmodes.as_ref().unwrap();
- let res = unsafe { libc::tcsetattr(STDIN_FILENO, TCSADRAIN, termios) };
- if res < 0 {
+ let tmodes = tmodes.as_ref().unwrap();
+ if termios::tcsetattr(
+ unsafe { BorrowedFd::borrow_raw(STDIN_FILENO) },
+ termios::SetArg::TCSADRAIN,
+ tmodes,
+ )
+ .is_err()
+ {
perror("tcsetattr");
}
}
diff --git a/src/builtins/fish_key_reader.rs b/src/builtins/fish_key_reader.rs
index ca1c94757..e33a23bac 100644
--- a/src/builtins/fish_key_reader.rs
+++ b/src/builtins/fish_key_reader.rs
@@ -47,7 +47,7 @@ fn should_exit(
for evt in [VINTR, VEOF] {
let modes = shell_modes();
- let cc = Key::from_single_byte(modes.c_cc[evt]);
+ let cc = Key::from_single_byte(modes.control_chars[evt]);
if match_key_event_to_key(&key_evt, &cc).is_some() {
if recent_keys
@@ -61,7 +61,7 @@ fn should_exit(
}
streams.err.append(&wgettext_fmt!(
"Press ctrl-%c again to exit\n",
- char::from(modes.c_cc[evt] + 0x60)
+ char::from(modes.control_chars[evt] + 0x60)
));
return false;
}
@@ -162,8 +162,8 @@ fn setup_and_process_keys(
let modes = shell_modes();
streams.err.appendln(&wgettext_fmt!(
"or press ctrl-%c or ctrl-%c twice in a row.",
- char::from(modes.c_cc[VINTR] + 0x60),
- char::from(modes.c_cc[VEOF] + 0x60)
+ char::from(modes.control_chars[VINTR] + 0x60),
+ char::from(modes.control_chars[VEOF] + 0x60)
));
streams.err.appendln(L!("\n"));
}
diff --git a/src/common.rs b/src/common.rs
index 854b6dc3a..d44b4c34e 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -19,6 +19,7 @@
use fish_widestring::{
ENCODE_DIRECT_END, decode_byte_from_char, encode_byte_to_char, subslice_position,
};
+use nix::sys::termios::Termios;
use std::env;
use std::ffi::{CStr, CString, OsStr, OsString};
use std::os::unix::prelude::*;
@@ -884,7 +885,7 @@ pub fn read_unquoted_escape(
Some(in_pos)
}
-pub fn shell_modes() -> MutexGuard<'static, libc::termios> {
+pub fn shell_modes() -> MutexGuard<'static, Termios> {
crate::reader::SHELL_MODES.lock().unwrap()
}
diff --git a/src/input_common.rs b/src/input_common.rs
index ded93594c..61fe0c1b6 100644
--- a/src/input_common.rs
+++ b/src/input_common.rs
@@ -878,7 +878,7 @@ fn readch(&mut self) -> CharEvent {
self.push_back(evt);
}
});
- let vintr = shell_modes().c_cc[libc::VINTR];
+ let vintr = shell_modes().control_chars[libc::VINTR];
if vintr != 0
&& key.is_some_and(|key| {
match_key_event_to_key(&key, &Key::from_single_byte(vintr))
@@ -1619,7 +1619,7 @@ fn prepare_to_select(&mut self) {}
fn select_interrupted(&mut self) {}
fn enqueue_interrupt_key(&mut self) {
- let vintr = shell_modes().c_cc[libc::VINTR];
+ let vintr = shell_modes().control_chars[libc::VINTR];
if vintr != 0 {
let interrupt_evt = CharEvent::from_key(KeyEvent::from_single_byte(vintr));
if stop_query(self.blocking_query()) {
diff --git a/src/job_group.rs b/src/job_group.rs
index d90d2b7f1..45aa79a57 100644
--- a/src/job_group.rs
+++ b/src/job_group.rs
@@ -2,6 +2,7 @@
use crate::prelude::*;
use crate::proc::{JobGroupRef, Pid};
use crate::signal::Signal;
+use nix::sys::termios::Termios;
use std::cell::RefCell;
use std::num::NonZeroU32;
use std::sync::atomic::{AtomicI32, Ordering};
@@ -60,7 +61,7 @@ fn to_arg(self) -> fish_printf::Arg<'a> {
pub struct JobGroup {
/// If set, the saved terminal modes of this job. This needs to be saved so that we can restore
/// the terminal to the same state when resuming a stopped job.
- pub tmodes: RefCell