diff -wpruN --no-dereference a~/src/builtins/fg.rs a/src/builtins/fg.rs
--- a~/src/builtins/fg.rs 2026-05-07 16:02:14.000000000 +0000
+++ a/src/builtins/fg.rs 2026-05-20 13:38:23.291989325 +0000
@@ -8,9 +8,7 @@ use crate::tokenizer::tok_command;
use crate::{env::EnvMode, tty_handoff::TtyHandoff};
use crate::{err_fmt, err_str};
use fish_util::perror;
-use libc::STDIN_FILENO;
-use nix::sys::termios::{self, tcsetattr};
-use std::os::fd::BorrowedFd;
+use libc::{STDIN_FILENO, TCSADRAIN};
use super::prelude::*;
@@ -140,14 +138,9 @@ pub fn fg(parser: &Parser, streams: &mut
}
let tmodes = job_group.tmodes.borrow();
if job_group.wants_terminal() && tmodes.is_some() {
- let tmodes = tmodes.as_ref().unwrap();
- if tcsetattr(
- unsafe { BorrowedFd::borrow_raw(STDIN_FILENO) },
- termios::SetArg::TCSADRAIN,
- tmodes,
- )
- .is_err()
- {
+ let termios = tmodes.as_ref().unwrap();
+ let res = unsafe { libc::tcsetattr(STDIN_FILENO, TCSADRAIN, termios) };
+ if res < 0 {
perror("tcsetattr");
}
}
diff -wpruN --no-dereference a~/src/builtins/fish_key_reader.rs a/src/builtins/fish_key_reader.rs
--- a~/src/builtins/fish_key_reader.rs 2026-05-07 16:02:14.000000000 +0000
+++ a/src/builtins/fish_key_reader.rs 2026-05-20 13:38:23.292319209 +0000
@@ -49,7 +49,7 @@ fn should_exit(
for evt in [VINTR, VEOF] {
let modes = shell_modes();
- let cc = Key::from_single_byte(modes.control_chars[evt]);
+ let cc = Key::from_single_byte(modes.c_cc[evt]);
if match_key_event_to_key(&key_evt, &cc).is_some() {
if recent_keys
@@ -63,7 +63,7 @@ fn should_exit(
}
streams.err.appendln(&wgettext_fmt!(
"Press ctrl-%c again to exit",
- char::from(modes.control_chars[evt] + 0x60)
+ char::from(modes.c_cc[evt] + 0x60)
));
return false;
}
@@ -164,8 +164,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.control_chars[VINTR] + 0x60),
- char::from(modes.control_chars[VEOF] + 0x60)
+ char::from(modes.c_cc[VINTR] + 0x60),
+ char::from(modes.c_cc[VEOF] + 0x60)
));
streams.err.appendln(L!("\n"));
}
diff -wpruN --no-dereference a~/src/common.rs a/src/common.rs
--- a~/src/common.rs 2026-05-07 16:02:14.000000000 +0000
+++ a/src/common.rs 2026-05-20 13:38:23.292733249 +0000
@@ -9,7 +9,6 @@ use crate::{
};
use fish_fallback::fish_wcwidth;
use fish_widestring::subslice_position;
-use nix::sys::termios::Termios;
use std::{
env,
sync::{MutexGuard, OnceLock, atomic::Ordering},
@@ -21,7 +20,7 @@ pub const BUILD_DIR: &str = env!("FISH_R
pub const PACKAGE_NAME: &str = env!("CARGO_PKG_NAME");
-pub fn shell_modes() -> MutexGuard<'static, Termios> {
+pub fn shell_modes() -> MutexGuard<'static, libc::termios> {
crate::reader::SHELL_MODES.lock().unwrap()
}
diff -wpruN --no-dereference a~/src/input_common.rs a/src/input_common.rs
--- a~/src/input_common.rs 2026-05-07 16:02:14.000000000 +0000
+++ a/src/input_common.rs 2026-05-20 13:38:23.293562243 +0000
@@ -877,7 +877,7 @@ pub trait InputEventQueuer {
self.push_back(evt);
}
});
- let vintr = shell_modes().control_chars[libc::VINTR];
+ let vintr = shell_modes().c_cc[libc::VINTR];
if vintr != 0
&& key.is_some_and(|key| {
match_key_event_to_key(&key, &Key::from_single_byte(vintr))
@@ -1618,7 +1618,7 @@ pub trait InputEventQueuer {
fn select_interrupted(&mut self) {}
fn enqueue_interrupt_key(&mut self) {
- let vintr = shell_modes().control_chars[libc::VINTR];
+ let vintr = shell_modes().c_cc[libc::VINTR];
if vintr != 0 {
let interrupt_evt = CharEvent::from_key(KeyEvent::from_single_byte(vintr));
if stop_query(self.blocking_query()) {
diff -wpruN --no-dereference a~/src/job_group.rs a/src/job_group.rs
--- a~/src/job_group.rs 2026-05-07 16:02:14.000000000 +0000
+++ a/src/job_group.rs 2026-05-20 13:38:23.293920516 +0000
@@ -2,7 +2,6 @@ use crate::global_safety::RelaxedAtomicB
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};
@@ -61,7 +60,7 @@ impl<'a> fish_printf::ToArg<'a> for Mayb
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