diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs index f3b970c834..d0fe9fef83 100644 --- a/src/header/signal/mod.rs +++ b/src/header/signal/mod.rs @@ -24,6 +24,7 @@ type SigSet = BitSet<[c_ulong; 1]>; pub const SIG_DFL: usize = 0; pub const SIG_IGN: usize = 1; pub const SIG_ERR: isize = -1; +pub const SIG_HOLD: isize = 2; pub const SIG_BLOCK: c_int = 0; pub const SIG_UNBLOCK: c_int = 1; @@ -231,14 +232,18 @@ pub extern "C" fn signal( unsafe { old_sa.assume_init() }.sa_handler } -// #[no_mangle] -pub extern "C" fn sigpause(sig: c_int) -> c_int { - unimplemented!(); +#[no_mangle] +pub unsafe extern "C" fn sigpause(sig: c_int) -> c_int { + let mut pset = mem::MaybeUninit::::uninit(); + sigprocmask(0, ptr::null_mut(), pset.as_mut_ptr()); + let mut set = pset.assume_init(); + sigdelset(&mut set, sig); + sigsuspend(&mut set) } -// #[no_mangle] +#[no_mangle] pub extern "C" fn sigpending(set: *mut sigset_t) -> c_int { - unimplemented!(); + Sys::sigpending(set) } #[no_mangle] @@ -246,19 +251,61 @@ pub extern "C" fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigse Sys::sigprocmask(how, set, oset) } -// #[no_mangle] -pub extern "C" fn sigrelse(sig: c_int) -> c_int { - unimplemented!(); +#[no_mangle] +pub unsafe extern "C" fn sigrelse(sig: c_int) -> c_int { + let mut pset = mem::MaybeUninit::::uninit(); + sigemptyset(pset.as_mut_ptr()); + let mut set = pset.assume_init(); + if sigaddset(&mut set, sig) < 0 { + return -1; + } + sigprocmask(SIG_UNBLOCK, &mut set, ptr::null_mut()) } -// #[no_mangle] -pub extern "C" fn sigset(sig: c_int, func: fn(c_int)) -> fn(c_int) { - unimplemented!(); +#[no_mangle] +pub unsafe extern "C" fn sigset( + sig: c_int, + func: Option +) -> Option { + let mut old_sa = mem::MaybeUninit::uninit(); + let mut pset = mem::MaybeUninit::::uninit(); + let sig_hold: Option = mem::transmute(SIG_HOLD); + let sig_err: Option = mem::transmute(SIG_ERR); + sigemptyset(pset.as_mut_ptr()); + let mut set = pset.assume_init(); + if sigaddset(&mut set, sig) < 0 { + return sig_err; + } else { + if func == sig_hold { + if sigaction(sig, ptr::null_mut(), old_sa.as_mut_ptr()) < 0 || + sigprocmask(SIG_BLOCK, &mut set, &mut set) < 0 { + mem::forget(old_sa); + return sig_err; + } + } else { + let mut sa = sigaction { + sa_handler: func, + sa_flags: 0 as c_ulong, + sa_restorer: Some(__restore_rt), + sa_mask: sigset_t::default(), + }; + sigemptyset(&mut sa.sa_mask); + if sigaction(sig, &sa, old_sa.as_mut_ptr()) < 0 || + sigprocmask(SIG_UNBLOCK, &mut set, &mut set) < 0 { + mem::forget(old_sa); + return sig_err; + } + } + } + if sigismember(&mut set, sig) == 1 { + return sig_hold; + } + old_sa.assume_init().sa_handler } -// #[no_mangle] +#[no_mangle] pub extern "C" fn sigsuspend(sigmask: *const sigset_t) -> c_int { - unimplemented!(); + Sys::sigsuspend(sigmask) } // #[no_mangle] diff --git a/src/platform/linux/signal.rs b/src/platform/linux/signal.rs index d8bf311c62..c0ab260539 100644 --- a/src/platform/linux/signal.rs +++ b/src/platform/linux/signal.rs @@ -5,7 +5,7 @@ use super::{ e, Sys, }; use crate::header::{ - signal::{sigaction, sigset_t, stack_t}, + signal::{NSIG, sigaction, sigset_t, stack_t}, sys_time::itimerval, }; @@ -51,7 +51,15 @@ impl PalSignal for Sys { e(unsafe { syscall!(SIGALTSTACK, ss, old_ss) }) as c_int } + fn sigpending(set: *mut sigset_t) -> c_int { + e(unsafe { syscall!(RT_SIGPENDING, set, NSIG/8) }) as c_int + } + fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int { e(unsafe { syscall!(RT_SIGPROCMASK, how, set, oset, mem::size_of::()) }) as c_int } + + fn sigsuspend(set: *const sigset_t) -> c_int { + e(unsafe { syscall!(RT_SIGSUSPEND, set, NSIG/8) }) as c_int + } } diff --git a/src/platform/pal/signal.rs b/src/platform/pal/signal.rs index b432f57922..a91c69d8c6 100644 --- a/src/platform/pal/signal.rs +++ b/src/platform/pal/signal.rs @@ -19,5 +19,9 @@ pub trait PalSignal: Pal { fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int; + fn sigpending(set: *mut sigset_t) -> c_int; + fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int; + + fn sigsuspend(set: *const sigset_t) -> c_int; } diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs index 801d947d95..ebbea5f2b7 100644 --- a/src/platform/redox/signal.rs +++ b/src/platform/redox/signal.rs @@ -7,7 +7,7 @@ use super::{ }; use crate::{ header::{ - errno::EINVAL, + errno::{EINVAL, ENOSYS}, signal::{sigaction, sigset_t, stack_t}, sys_time::{itimerval, ITIMER_REAL}, }, @@ -135,6 +135,11 @@ impl PalSignal for Sys { unimplemented!() } + fn sigpending(set: *mut sigset_t) -> c_int { + platform::errno = ENOSYS; + -1 + } + fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int { let new_opt = if set.is_null() { None @@ -152,4 +157,9 @@ impl PalSignal for Sys { } ret } + + fn sigsuspend(set: *const sigset_t) -> c_int { + platform::errno = ENOSYS; + -1 + } }