guard signal-handling init more broadly

If `install_signal_handlers` is false (due to embedding),
the VM still inits the signal stdlib and installs a lot
of signal-handling, including touching *ever* signal,
including SIGINT.

When running multiple concurrent interpreters with
varying inits at varying times, this can break the
hosting application's signal-handling so lovingly
set up before starting anything with RustPython.
This commit is contained in:
Bob McWhirter authored and Noa committed 2025-01-09 16:21:25 -06:00
1 parent e2a55cbf34
commit d06459fa49
1 file changed
+21 -21
+21 -21
View File
@@ -110,28 +110,28 @@ pub(crate) mod _signal {
module: &Py<crate::builtins::PyModule>,
vm: &VirtualMachine,
) {
let sig_dfl = vm.new_pyobj(SIG_DFL as u8);
let sig_ign = vm.new_pyobj(SIG_IGN as u8);
for signum in 1..NSIG {
let handler = unsafe { libc::signal(signum as i32, SIG_IGN) };
if handler != SIG_ERR {
unsafe { libc::signal(signum as i32, handler) };
}
let py_handler = if handler == SIG_DFL {
Some(sig_dfl.clone())
} else if handler == SIG_IGN {
Some(sig_ign.clone())
} else {
None
};
vm.signal_handlers.as_deref().unwrap().borrow_mut()[signum] = py_handler;
}
let int_handler = module
.get_attr("default_int_handler", vm)
.expect("_signal does not have this attr?");
if vm.state.settings.install_signal_handlers {
let sig_dfl = vm.new_pyobj(SIG_DFL as u8);
let sig_ign = vm.new_pyobj(SIG_IGN as u8);
for signum in 1..NSIG {
let handler = unsafe { libc::signal(signum as i32, SIG_IGN) };
if handler != SIG_ERR {
unsafe { libc::signal(signum as i32, handler) };
}
let py_handler = if handler == SIG_DFL {
Some(sig_dfl.clone())
} else if handler == SIG_IGN {
Some(sig_ign.clone())
} else {
None
};
vm.signal_handlers.as_deref().unwrap().borrow_mut()[signum] = py_handler;
}
let int_handler = module
.get_attr("default_int_handler", vm)
.expect("_signal does not have this attr?");
signal(libc::SIGINT, int_handler, vm).expect("Failed to set sigint handler");
}
}