diff --git a/src/header/signal/linux.rs b/src/header/signal/linux.rs index cfa63b556353681d4a988bd340a417883c77b011..d7339c9e792fbe4989526cce34fddf912a87db8b 100644 --- a/src/header/signal/linux.rs +++ b/src/header/signal/linux.rs @@ -64,3 +64,8 @@ pub const SA_RESTART: usize = 0x1000_0000; pub const SA_NODEFER: usize = 0x4000_0000; pub const SA_RESETHAND: usize = 0x8000_0000; pub const SA_RESTORER: usize = 0x0400_0000; + +pub const SS_ONSTACK: usize = 1; +pub const SS_DISABLE: usize = 2; + +pub const MINSIGSTKSZ: usize = 2048; diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs index f3c0620363d872f149c7acde1f8ea407e0d2ebe5..1e130cdca3869066ab27ec0aff105fb96a630d7a 100644 --- a/src/header/signal/mod.rs +++ b/src/header/signal/mod.rs @@ -36,6 +36,14 @@ pub struct sigaction { pub sa_mask: sigset_t, } +#[repr(C)] +#[derive(Clone)] +pub struct stack_t { + pub ss_sp: *mut c_void, + pub ss_flags: c_int, + pub ss_size: c_uint, +} + pub type sigset_t = c_ulong; #[no_mangle] @@ -99,6 +107,20 @@ pub extern "C" fn sigaddset(set: *mut sigset_t, signo: c_int) -> c_int { 0 } +#[no_mangle] +pub unsafe extern "C" fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int { + if !ss.is_null() { + if (*ss).ss_flags != SS_DISABLE as c_int { + return errno::EINVAL; + } + if (*ss).ss_size < MINSIGSTKSZ as c_uint { + return errno::ENOMEM; + } + } + + Sys::sigaltstack(ss, old_ss) +} + #[no_mangle] pub extern "C" fn sigdelset(set: *mut sigset_t, signo: c_int) -> c_int { if signo <= 0 || signo as usize > NSIG { diff --git a/src/header/signal/redox.rs b/src/header/signal/redox.rs index e13787ee868639010b1e52466a98313a3f5cb6be..21c1ba13f7419dbc13d1de1b4c0e76d4df10f4f2 100644 --- a/src/header/signal/redox.rs +++ b/src/header/signal/redox.rs @@ -61,3 +61,8 @@ pub const SA_ONSTACK: usize = 0x08000000; pub const SA_RESTART: usize = 0x10000000; pub const SA_NODEFER: usize = 0x40000000; pub const SA_RESETHAND: usize = 0x80000000; + +pub const SS_ONSTACK: usize = 0x00000001; +pub const SS_DISABLE: usize = 0x00000002; + +pub const MINSIGSTKSZ: usize = 2048; diff --git a/src/platform/linux/signal.rs b/src/platform/linux/signal.rs index 7680a9f867d2ceafddf203a8ad449f695f8d1731..7e47729beaeda37ac402790004a32d3b620e1c5b 100644 --- a/src/platform/linux/signal.rs +++ b/src/platform/linux/signal.rs @@ -3,7 +3,7 @@ use core::mem; use super::super::types::*; use super::super::PalSignal; use super::{e, Sys}; -use header::signal::{sigaction, sigset_t}; +use header::signal::{sigaction, sigset_t, stack_t}; use header::sys_time::itimerval; impl PalSignal for Sys { @@ -42,6 +42,10 @@ impl PalSignal for Sys { )) as c_int } + fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int { + e(unsafe { syscall!(SIGALTSTACK, ss, old_ss) }) 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::<sigset_t>()) }) as c_int } diff --git a/src/platform/pal/signal.rs b/src/platform/pal/signal.rs index 60a633c248dc6ad89453313d4c347b3b3701ff64..d014ce89ee0bf4ab0f7cbdb7774cd6ac5a6a7ed1 100644 --- a/src/platform/pal/signal.rs +++ b/src/platform/pal/signal.rs @@ -1,6 +1,6 @@ use super::super::types::*; use super::super::Pal; -use header::signal::{sigaction, sigset_t}; +use header::signal::{sigaction, sigset_t, stack_t}; use header::sys_time::itimerval; pub trait PalSignal: Pal { @@ -16,5 +16,7 @@ pub trait PalSignal: Pal { unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int; + fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int; + fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int; } diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs index 28caf99c598f8f8a161aeee6e33a84261c714e2f..c3d28604d3ae1a81101ba5437a32a5c24ee39213 100644 --- a/src/platform/redox/signal.rs +++ b/src/platform/redox/signal.rs @@ -5,7 +5,7 @@ use super::super::types::*; use super::super::{Pal, PalSignal}; use super::{e, Sys}; use header::errno::EINVAL; -use header::signal::{sigaction, sigset_t}; +use header::signal::{sigaction, sigset_t, stack_t}; use header::sys_time::{itimerval, ITIMER_REAL}; use platform::errno; @@ -130,6 +130,10 @@ impl PalSignal for Sys { ret } + fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int { + unimplemented!() + } + fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int { let new_opt = if set.is_null() { None