From fa1a128aeb6dafd51902cee915b7a01093a5f1d9 Mon Sep 17 00:00:00 2001 From: Daniel Rainer Date: Tue, 20 Jan 2026 18:37:01 +0100 Subject: [PATCH] nix: use `getpgrp` wrapper Part of #12380 --- Cargo.toml | 1 + src/exec.rs | 3 ++- src/nix.rs | 3 --- src/proc.rs | 9 ++++++--- src/reader/reader.rs | 9 +++++---- src/tty_handoff.rs | 7 ++++--- 6 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 43bfda7ea..43f995e43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ nix = { version = "0.30.1", default-features = false, features = [ "fs", "inotify", "resource", + "process", "signal", "term", "user", diff --git a/src/exec.rs b/src/exec.rs index 4a0f098d8..52d8fd5b0 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -54,6 +54,7 @@ }; use nix::fcntl::OFlag; use nix::sys::stat; +use nix::unistd::getpgrp; use std::ffi::CStr; use std::io::{Read, Write}; use std::mem::MaybeUninit; @@ -702,7 +703,7 @@ fn fork_child_for_process( // Claim the tty from fish, if the job wants it and we are the pgroup leader. let claim_tty_from = if p.leads_pgrp && job.group().wants_terminal() { // getpgrp(2) cannot fail and always returns the (positive) caller's pgid - Some(NonZeroU32::new(crate::nix::getpgrp() as u32).unwrap()) + Some(NonZeroU32::new(getpgrp().as_raw() as u32).unwrap()) } else { None }; diff --git a/src/nix.rs b/src/nix.rs index b86bd8a69..57e2ec58f 100644 --- a/src/nix.rs +++ b/src/nix.rs @@ -26,9 +26,6 @@ fn as_duration(&self) -> Duration { } } -pub fn getpgrp() -> i32 { - unsafe { libc::getpgrp() } -} pub fn getpid() -> i32 { unsafe { libc::getpid() } } diff --git a/src/proc.rs b/src/proc.rs index 3a55b9ecb..63c74a9b2 100644 --- a/src/proc.rs +++ b/src/proc.rs @@ -29,7 +29,10 @@ SIGKILL, SIGPIPE, SIGQUIT, SIGSEGV, SIGSYS, SIGTTOU, STDOUT_FILENO, WCONTINUED, WEXITSTATUS, WIFCONTINUED, WIFEXITED, WIFSIGNALED, WIFSTOPPED, WNOHANG, WTERMSIG, WUNTRACED, }; -use nix::sys::signal::{SaFlags, SigAction, SigHandler, SigSet}; +use nix::{ + sys::signal::{SaFlags, SigAction, SigHandler, SigSet}, + unistd::getpgrp, +}; use std::cell::{Cell, Ref, RefCell, RefMut}; use std::fs; use std::io::{Read, Write}; @@ -1107,11 +1110,11 @@ pub fn proc_wait_any(parser: &Parser) { /// Send SIGHUP to the list `jobs`, excepting those which are in fish's pgroup. pub fn hup_jobs(jobs: &JobList) { - let fish_pgrp = crate::nix::getpgrp(); + let fish_pgrp = getpgrp(); let mut kill_list = Vec::new(); for j in jobs { let Some(pgid) = j.get_pgid() else { continue }; - if pgid.as_pid_t() != fish_pgrp && !j.is_completed() { + if pgid.as_pid_t() != fish_pgrp.as_raw() && !j.is_completed() { j.signal(SIGHUP); if j.is_stopped() { j.signal(SIGCONT); diff --git a/src/reader/reader.rs b/src/reader/reader.rs index aadd395d9..3499d7fc7 100644 --- a/src/reader/reader.rs +++ b/src/reader/reader.rs @@ -28,6 +28,7 @@ }; use nix::fcntl::OFlag; use nix::sys::stat::Mode; +use nix::unistd::getpgrp; use std::borrow::Cow; use std::cell::UnsafeCell; use std::cmp; @@ -98,7 +99,7 @@ use crate::io::IoChain; use crate::key::ViewportPosition; use crate::kill::{kill_add, kill_replace, kill_yank, kill_yank_rotate}; -use crate::nix::{getpgrp, getpid, isatty}; +use crate::nix::{getpid, isatty}; use crate::operation_context::{OperationContext, get_bg_context}; use crate::pager::{PageRendering, Pager, SelectionMotion}; use crate::panic::AT_EXIT; @@ -1018,7 +1019,7 @@ pub fn reader_init(will_restore_foreground_pgroup: bool) { // Set up our fixed terminal modes once, // so we don't get flow control just because we inherited it. - if is_interactive_session() && getpgrp() == unsafe { libc::tcgetpgrp(STDIN_FILENO) } { + if is_interactive_session() && getpgrp().as_raw() == unsafe { libc::tcgetpgrp(STDIN_FILENO) } { term_donate(/*quiet=*/ true); } } @@ -1036,7 +1037,7 @@ pub fn reader_deinit(restore_foreground_pgroup: bool) { /// otherwise we won't think we own the terminal. /// THIS FUNCTION IS CALLED FROM A SIGNAL HANDLER. IT MUST BE ASYNC-SIGNAL-SAFE. pub fn safe_restore_term_mode() { - if !is_interactive_session() || getpgrp() != unsafe { libc::tcgetpgrp(STDIN_FILENO) } { + if !is_interactive_session() || getpgrp().as_raw() != unsafe { libc::tcgetpgrp(STDIN_FILENO) } { return; } if let Some(modes) = safe_get_terminal_mode_on_startup() { @@ -4933,7 +4934,7 @@ fn acquire_tty_or_exit(shell_pgid: libc::pid_t) { fn reader_interactive_init() { assert_is_main_thread(); - let mut shell_pgid = getpgrp(); + let mut shell_pgid = getpgrp().as_raw(); let shell_pid = getpid(); // Ensure interactive signal handling is enabled. diff --git a/src/tty_handoff.rs b/src/tty_handoff.rs index 4639985c5..8c25e24e5 100644 --- a/src/tty_handoff.rs +++ b/src/tty_handoff.rs @@ -20,6 +20,7 @@ use crate::wutil::{perror, wcstoi}; use fish_widestring::ToWString; use libc::{EINVAL, ENOTTY, EPERM, STDIN_FILENO, WNOHANG}; +use nix::unistd::getpgrp; use std::mem::MaybeUninit; use std::sync::{ OnceLock, @@ -427,10 +428,10 @@ fn try_transfer(jg: &JobGroup) -> bool { let pgid = jg.get_pgid().unwrap(); // It should never be fish's pgroup. - let fish_pgrp = crate::nix::getpgrp(); + let fish_pgrp = getpgrp(); assert_ne!( pgid.as_pid_t(), - fish_pgrp, + fish_pgrp.as_raw(), "Job should not have fish's pgroup" ); @@ -455,7 +456,7 @@ fn try_transfer(jg: &JobGroup) -> bool { } else if current_owner == pgid.get() { // Case 2. return true; - } else if current_owner != pgid.get() && current_owner != fish_pgrp { + } else if current_owner != pgid.get() && current_owner != fish_pgrp.as_raw() { // Case 3. return false; }