diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs index 0ce5ec9d490e6d9f5b7df41df305ff6ff3086289..bf36e6d9af6c1609f1ace4c5fa47926318561234 100644 --- a/src/header/signal/mod.rs +++ b/src/header/signal/mod.rs @@ -1,6 +1,6 @@ //! signal implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/signal.h.html -use core::{mem, ptr}; +use core::mem; use cbitset::BitSet; @@ -21,20 +21,20 @@ pub mod sys; type SigSet = BitSet<[c_ulong; 1]>; -pub (crate) const SIG_DFL: usize = 0; -pub (crate) const SIG_IGN: usize = 1; -pub (crate) const SIG_ERR: isize = -1; +pub(crate) const SIG_DFL: usize = 0; +pub(crate) const SIG_IGN: usize = 1; +pub(crate) const SIG_ERR: isize = -1; pub const SIG_BLOCK: c_int = 0; pub const SIG_UNBLOCK: c_int = 1; pub const SIG_SETMASK: c_int = 2; #[repr(C)] -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct sigaction { - pub sa_handler: extern "C" fn(c_int), + pub sa_handler: Option<extern "C" fn(c_int)>, pub sa_flags: c_ulong, - pub sa_restorer: unsafe extern "C" fn(), + pub sa_restorer: Option<unsafe extern "C" fn()>, pub sa_mask: sigset_t, } @@ -86,14 +86,12 @@ pub unsafe extern "C" fn sigaction( act: *const sigaction, oact: *mut sigaction, ) -> c_int { - let act_opt = if !act.is_null() { - let mut act_clone = (*act).clone(); + let act_opt = act.as_ref().map(|act| { + let mut act_clone = act.clone(); act_clone.sa_flags |= SA_RESTORER as c_ulong; - Some(act_clone) - } else { - None - }; - Sys::sigaction(sig, act_opt.map_or(ptr::null_mut(), |x| &x), oact) + act_clone + }); + Sys::sigaction(sig, act_opt.as_ref(), oact.as_mut()) } #[no_mangle] @@ -194,11 +192,14 @@ extern "C" { } #[no_mangle] -pub extern "C" fn signal(sig: c_int, func: extern "C" fn(c_int)) -> extern "C" fn(c_int) { +pub extern "C" fn signal( + sig: c_int, + func: Option<extern "C" fn(c_int)>, +) -> Option<extern "C" fn(c_int)> { let sa = sigaction { sa_handler: func, sa_flags: SA_RESTART as c_ulong, - sa_restorer: __restore_rt, + sa_restorer: Some(__restore_rt), sa_mask: sigset_t::default(), }; let mut old_sa = unsafe { mem::uninitialized() }; diff --git a/src/platform/linux/signal.rs b/src/platform/linux/signal.rs index 6980dedcc0277295edfe624267172afda2710de8..d8bf311c6208703bc598ba39709c022cc0e6025f 100644 --- a/src/platform/linux/signal.rs +++ b/src/platform/linux/signal.rs @@ -35,14 +35,16 @@ impl PalSignal for Sys { e(unsafe { syscall!(SETITIMER, which, new, old) }) as c_int } - unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int { - e(syscall!( - RT_SIGACTION, - sig, - act, - oact, - mem::size_of::<sigset_t>() - )) as c_int + fn sigaction(sig: c_int, act: Option<&sigaction>, oact: Option<&mut sigaction>) -> c_int { + e(unsafe { + syscall!( + RT_SIGACTION, + sig, + act.map_or_else(core::ptr::null, |x| x as *const _), + oact.map_or_else(core::ptr::null_mut, |x| x as *mut _), + mem::size_of::<sigset_t>() + ) + }) as c_int } fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int { diff --git a/src/platform/pal/signal.rs b/src/platform/pal/signal.rs index b2ebf71acad96beead12340dfffecda8e1870892..b432f57922969f15afb6a3a9ad029ed98cb7bf3f 100644 --- a/src/platform/pal/signal.rs +++ b/src/platform/pal/signal.rs @@ -15,7 +15,7 @@ pub trait PalSignal: Pal { fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int; - unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int; + fn sigaction(sig: c_int, act: Option<&sigaction>, oact: Option<&mut sigaction>) -> c_int; fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int; diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs index 8a275af3b82b1fbc46a5c341f0243c5956b1ce48..6032a37fcf11284aac042bc36d4ddc94a29d7703 100644 --- a/src/platform/redox/signal.rs +++ b/src/platform/redox/signal.rs @@ -105,33 +105,28 @@ impl PalSignal for Sys { 0 } - unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int { - let new_opt = if act.is_null() { - None - } else { - let m = (*act).sa_mask; - Some(syscall::SigAction { - sa_handler: mem::transmute((*act).sa_handler), + fn sigaction(sig: c_int, act: Option<&sigaction>, oact: Option<&mut sigaction>) -> c_int { + let new_opt = act.map(|act| { + let m = act.sa_mask; + let sa_handler = unsafe { mem::transmute(act.sa_handler) }; + syscall::SigAction { + sa_handler, sa_mask: [m as u64, 0], - sa_flags: syscall::SigActionFlags::from_bits((*act).sa_flags as usize) + sa_flags: syscall::SigActionFlags::from_bits(act.sa_flags as usize) .expect("sigaction: invalid bit pattern"), - }) - }; - let mut old_opt = if oact.is_null() { - None - } else { - Some(syscall::SigAction::default()) - }; + } + }); + let mut old_opt = oact.as_ref().map(|_| syscall::SigAction::default()); let ret = e(syscall::sigaction( sig as usize, new_opt.as_ref(), old_opt.as_mut(), )) as c_int; - if let Some(old) = old_opt { - (*oact).sa_handler = mem::transmute(old.sa_handler); + if let (Some(old), Some(oact)) = (old_opt, oact) { + oact.sa_handler = unsafe { mem::transmute(old.sa_handler) }; let m = old.sa_mask; - (*oact).sa_mask = m[0] as c_ulong; - (*oact).sa_flags = old.sa_flags.bits() as c_ulong; + oact.sa_mask = m[0] as c_ulong; + oact.sa_flags = old.sa_flags.bits() as c_ulong; } ret } diff --git a/tests/Makefile b/tests/Makefile index 388720a45847f850f683b207592bc23c6336320f..4f5e83f67b0f0952e71743948cd46a816a3bf6c8 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -96,11 +96,11 @@ EXPECT_NAMES=\ wchar/wcsrchr \ wchar/wcstod \ wchar/wcstok \ - wchar/wcstol + wchar/wcstol \ + signal # TODO: Fix these # netdb/getaddrinfo \ # netdb/netdb \ - # signal # Binaries that may generate varied output NAMES=\ diff --git a/tests/expected/signal.stderr b/tests/expected/signal.stderr new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/expected/signal.stdout b/tests/expected/signal.stdout new file mode 100644 index 0000000000000000000000000000000000000000..7d184e34c823485133f02e17a6993d8067578e78 --- /dev/null +++ b/tests/expected/signal.stdout @@ -0,0 +1,3 @@ +Raising... +Signal handler called! +Raised. diff --git a/tests/signal.c b/tests/signal.c index b192ad397def2bc139a0767e8a76480b1e0b5fc5..b322201b8cd30ad92ccc2b5d56e27f78d1a33c8d 100644 --- a/tests/signal.c +++ b/tests/signal.c @@ -11,8 +11,10 @@ void handler(int sig) { } int main(void) { - void (*signal_status)(int) = signal(SIGUSR1, &handler); + void (*signal_status)(int) = signal(SIGUSR1, handler); ERROR_IF(signal, signal_status, == SIG_ERR); + signal_status = signal(SIGUSR1, handler); + ERROR_IF(signal, signal_status, != handler); puts("Raising...");