(
how: i32,
mask: crate::function::ArgIterable,
vm: &VirtualMachine,
)
| 624 | #[cfg(unix)] |
| 625 | #[pyfunction] |
| 626 | fn pthread_sigmask( |
| 627 | how: i32, |
| 628 | mask: crate::function::ArgIterable, |
| 629 | vm: &VirtualMachine, |
| 630 | ) -> PyResult { |
| 631 | use crate::convert::IntoPyException; |
| 632 | |
| 633 | // Initialize sigset |
| 634 | let mut sigset: libc::sigset_t = unsafe { core::mem::zeroed() }; |
| 635 | // SAFETY: sigset is a valid pointer |
| 636 | if unsafe { libc::sigemptyset(&mut sigset) } != 0 { |
| 637 | return Err(std::io::Error::last_os_error().into_pyexception(vm)); |
| 638 | } |
| 639 | |
| 640 | // Add signals to the set |
| 641 | for sig in mask.iter(vm)? { |
| 642 | let sig = sig?; |
| 643 | // Convert to i32, handling overflow by returning ValueError |
| 644 | let signum: i32 = sig.try_to_value(vm).map_err(|_| { |
| 645 | vm.new_value_error(format!( |
| 646 | "signal number out of range [1, {}]", |
| 647 | signal::NSIG - 1 |
| 648 | )) |
| 649 | })?; |
| 650 | // Validate signal number is in range [1, NSIG) |
| 651 | if signum < 1 || signum >= signal::NSIG as i32 { |
| 652 | return Err(vm.new_value_error(format!( |
| 653 | "signal number {} out of range [1, {}]", |
| 654 | signum, |
| 655 | signal::NSIG - 1 |
| 656 | ))); |
| 657 | } |
| 658 | // SAFETY: sigset is a valid pointer and signum is validated |
| 659 | if unsafe { libc::sigaddset(&mut sigset, signum) } != 0 { |
| 660 | return Err(std::io::Error::last_os_error().into_pyexception(vm)); |
| 661 | } |
| 662 | } |
| 663 | |
| 664 | // Call pthread_sigmask |
| 665 | let mut old_mask: libc::sigset_t = unsafe { core::mem::zeroed() }; |
| 666 | // SAFETY: all pointers are valid |
| 667 | let err = unsafe { libc::pthread_sigmask(how, &sigset, &mut old_mask) }; |
| 668 | if err != 0 { |
| 669 | return Err(std::io::Error::from_raw_os_error(err).into_pyexception(vm)); |
| 670 | } |
| 671 | |
| 672 | // Check for pending signals |
| 673 | signal::check_signals(vm)?; |
| 674 | |
| 675 | // Convert old mask to Python set |
| 676 | sigset_to_pyset(&old_mask, vm) |
| 677 | } |
| 678 | |
| 679 | #[cfg(any(unix, windows))] |
| 680 | pub extern "C" fn run_signal(signum: i32) { |
nothing calls this directly
no test coverage detected