mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-12-19 05:13:44 +08:00
posix_spawn: Unconditionally default all signals (except HUP)
Some checks are pending
make test / ubuntu (push) Waiting to run
make test / ubuntu-32bit-static-pcre2 (push) Waiting to run
make test / ubuntu-asan (push) Waiting to run
make test / macos (push) Waiting to run
Rust checks / rustfmt (push) Waiting to run
Rust checks / clippy (push) Waiting to run
Rust checks / cargo-deny (push) Waiting to run
Some checks are pending
make test / ubuntu (push) Waiting to run
make test / ubuntu-32bit-static-pcre2 (push) Waiting to run
make test / ubuntu-asan (push) Waiting to run
make test / macos (push) Waiting to run
Rust checks / rustfmt (push) Waiting to run
Rust checks / clippy (push) Waiting to run
Rust checks / cargo-deny (push) Waiting to run
We don't really care if the process has a custom handler installed, we can just set it to default. The one we check is SIGHUP, which may be given to us via `nohup`. This saves ~30 syscalls *per process* we spawn, so: ```fish for f in (seq 1000) command true end ``` has ~30000 fewer rt_sigaction calls. These take up about ~30% of the total time spent in syscalls according to strace. We could also compute this set once at startup and then reuse it.
This commit is contained in:
parent
5d10bc6a02
commit
4859606e0c
|
@ -3,7 +3,7 @@
|
|||
use super::blocked_signals_for_job;
|
||||
use crate::proc::Job;
|
||||
use crate::redirection::Dup2List;
|
||||
use crate::signal::get_signals_with_handlers;
|
||||
use crate::signal::get_signals_to_default;
|
||||
use crate::{exec::is_thompson_shell_script, libc::_PATH_BSHELL};
|
||||
use errno::Errno;
|
||||
use libc::{c_char, posix_spawn_file_actions_t, posix_spawnattr_t};
|
||||
|
@ -126,8 +126,7 @@ impl PosixSpawner {
|
|||
}
|
||||
|
||||
// Everybody gets default handlers.
|
||||
let mut sigdefault: libc::sigset_t = unsafe { std::mem::zeroed() };
|
||||
get_signals_with_handlers(&mut sigdefault);
|
||||
let sigdefault = get_signals_to_default();
|
||||
attr.set_sigdefault(&sigdefault)?;
|
||||
|
||||
// Reset the sigmask.
|
||||
|
|
|
@ -275,21 +275,23 @@ pub fn signal_handle(sig: Signal) {
|
|||
sigaction(sig, &act, std::ptr::null_mut());
|
||||
}
|
||||
|
||||
pub fn get_signals_with_handlers(set: &mut libc::sigset_t) {
|
||||
unsafe { libc::sigemptyset(set) };
|
||||
pub fn get_signals_to_default() -> libc::sigset_t {
|
||||
let mut set: libc::sigset_t = unsafe { std::mem::zeroed() };
|
||||
unsafe { libc::sigemptyset(&mut set) };
|
||||
for data in SIGNAL_TABLE.iter() {
|
||||
let mut act: libc::sigaction = unsafe { std::mem::zeroed() };
|
||||
unsafe { libc::sigaction(data.signal.code(), std::ptr::null(), &mut act) };
|
||||
// If SIGHUP is being ignored (e.g., because were were run via `nohup`) don't reset it.
|
||||
// We don't special case other signals because if they're being ignored that shouldn't
|
||||
// affect processes we spawn. They should get the default behavior for those signals.
|
||||
if data.signal == libc::SIGHUP && act.sa_sigaction == libc::SIG_IGN {
|
||||
if data.signal == libc::SIGHUP {
|
||||
let mut act: libc::sigaction = unsafe { std::mem::zeroed() };
|
||||
unsafe { libc::sigaction(data.signal.code(), std::ptr::null(), &mut act) };
|
||||
if act.sa_sigaction == libc::SIG_IGN {
|
||||
continue;
|
||||
}
|
||||
if act.sa_sigaction != libc::SIG_DFL {
|
||||
unsafe { libc::sigaddset(set, data.signal.code()) };
|
||||
}
|
||||
unsafe { libc::sigaddset(&mut set, data.signal.code()) };
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
/// Ensure we did not inherit any blocked signals. See issue #3964.
|
||||
|
|
Loading…
Reference in New Issue
Block a user