diff --git a/src/header/signal/cbindgen.toml b/src/header/signal/cbindgen.toml index 46bbe113522ce57174074b555d76ac7aa337c271..14ec586ebc10924772373f4891f97a7a64931675 100644 --- a/src/header/signal/cbindgen.toml +++ b/src/header/signal/cbindgen.toml @@ -1,4 +1,4 @@ -sys_includes = ["stdint.h", "sys/types.h"] +sys_includes = ["stdint.h", "sys/types.h", "time.h"] include_guard = "_RELIBC_SIGNAL_H" trailer = "#include <bits/signal.h>" language = "C" @@ -12,3 +12,6 @@ cpp_compat = true [enum] prefix_with_name = true + +[export.rename] +"timespec" = "struct timespec" diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs index d0fe9fef83b819cb4fc797f53ca49869fe7a1961..1e4d37f92406c876b8b20eacb9a6b568cf8788f0 100644 --- a/src/header/signal/mod.rs +++ b/src/header/signal/mod.rs @@ -5,8 +5,11 @@ use core::{mem, ptr}; use cbitset::BitSet; use crate::{ - header::errno, - platform::{self, types::*, PalSignal, Sys}, + header::{ + errno, + time::timespec, + }, + platform::{self, types::*, Pal, PalSignal, Sys}, }; pub use self::sys::*; @@ -47,6 +50,16 @@ pub struct sigaltstack { pub ss_size: size_t, } +#[repr(C)] +#[derive(Clone, Debug)] +pub struct siginfo_t { + pub si_signo: c_int, + pub si_errno: c_int, + pub si_code: c_int, + _padding: [c_int; 29], + _si_align: [usize; 0], +} + pub type sigset_t = c_ulong; pub type stack_t = sigaltstack; @@ -308,9 +321,22 @@ pub extern "C" fn sigsuspend(sigmask: *const sigset_t) -> c_int { Sys::sigsuspend(sigmask) } -// #[no_mangle] +#[no_mangle] pub extern "C" fn sigwait(set: *const sigset_t, sig: *mut c_int) -> c_int { - unimplemented!(); + let mut pinfo = mem::MaybeUninit::<siginfo_t>::uninit(); + if sigtimedwait(set, pinfo.as_mut_ptr(), ptr::null_mut()) < 0 { + return -1; + } + unsafe { + let mut info = pinfo.assume_init(); + (*sig) = info.si_signo; + } + 0 +} + +#[no_mangle] +pub extern "C" fn sigtimedwait(set: *const sigset_t, sig: *mut siginfo_t, tp: *const timespec) -> c_int { + Sys::sigtimedwait(set, sig, tp) } pub const _signal_strings: [&str; 32] = [ diff --git a/src/platform/linux/signal.rs b/src/platform/linux/signal.rs index c0ab2605396f6e5071fe16710250c5cfc2716fd4..d12cf8b800c1f0433b5d00c8561aa9ee11b34370 100644 --- a/src/platform/linux/signal.rs +++ b/src/platform/linux/signal.rs @@ -5,8 +5,9 @@ use super::{ e, Sys, }; use crate::header::{ - signal::{NSIG, sigaction, sigset_t, stack_t}, + signal::{NSIG, sigaction, siginfo_t, sigset_t, stack_t}, sys_time::itimerval, + time::timespec, }; impl PalSignal for Sys { @@ -62,4 +63,8 @@ impl PalSignal for Sys { fn sigsuspend(set: *const sigset_t) -> c_int { e(unsafe { syscall!(RT_SIGSUSPEND, set, NSIG/8) }) as c_int } + + fn sigtimedwait(set: *const sigset_t, sig: *mut siginfo_t, tp: *const timespec) -> c_int { + e(unsafe { syscall!(RT_SIGTIMEDWAIT, set, sig, tp, NSIG/8) }) as c_int + } } diff --git a/src/platform/pal/signal.rs b/src/platform/pal/signal.rs index a91c69d8c61814f4f11959215c302c36eb042cf9..8441e6608c4a53cbe2d039e36db2482dd7187d0b 100644 --- a/src/platform/pal/signal.rs +++ b/src/platform/pal/signal.rs @@ -1,7 +1,8 @@ use super::super::{types::*, Pal}; use crate::header::{ - signal::{sigaction, sigset_t, stack_t}, + signal::{sigaction, siginfo_t, sigset_t, stack_t}, sys_time::itimerval, + time::timespec, }; pub trait PalSignal: Pal { @@ -24,4 +25,6 @@ pub trait PalSignal: Pal { fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int; fn sigsuspend(set: *const sigset_t) -> c_int; + + fn sigtimedwait(set: *const sigset_t, sig: *mut siginfo_t, tp: *const timespec) -> c_int; } diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs index e406bec8ff5b58e4d535b94925355f0fcced1f1f..3fb367fc1fd4e6c45d4d688c0c4df5c2f685a231 100644 --- a/src/platform/redox/signal.rs +++ b/src/platform/redox/signal.rs @@ -8,8 +8,9 @@ use super::{ use crate::{ header::{ errno::{EINVAL, ENOSYS}, - signal::{sigaction, sigset_t, stack_t}, + signal::{sigaction, siginfo_t, sigset_t, stack_t}, sys_time::{itimerval, ITIMER_REAL}, + time::timespec, }, platform::errno, }; @@ -166,4 +167,11 @@ impl PalSignal for Sys { } -1 } + + fn sigtimedwait(set: *const sigset_t, sig: *mut siginfo_t, tp: *const timespec) -> c_int { + unsafe { + errno = ENOSYS; + } + -1 + } }