Browse Source

Merge branch 'sigaltstack' into 'master'

Add sigaltstack

See merge request redox-os/relibc!218
jD91mZM2 5 years ago
parent
commit
8656c80614

+ 5 - 0
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;

+ 22 - 0
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 {

+ 5 - 0
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;

+ 5 - 1
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
     }

+ 3 - 1
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;
 }

+ 5 - 1
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