nix: use getpgrp wrapper

Part of #12380
This commit is contained in:
Daniel Rainer
2026-01-20 18:37:01 +01:00
committed by Johannes Altmanninger
parent 1f0a7e7697
commit fa1a128aeb
6 changed files with 18 additions and 14 deletions

View File

@@ -44,6 +44,7 @@ nix = { version = "0.30.1", default-features = false, features = [
"fs",
"inotify",
"resource",
"process",
"signal",
"term",
"user",

View File

@@ -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
};

View File

@@ -26,9 +26,6 @@ fn as_duration(&self) -> Duration {
}
}
pub fn getpgrp() -> i32 {
unsafe { libc::getpgrp() }
}
pub fn getpid() -> i32 {
unsafe { libc::getpid() }
}

View File

@@ -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);

View File

@@ -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.

View File

@@ -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;
}