Add sigtimedwait to test, and various fixes.

This commit is contained in:
4lDO2
2024-08-04 22:39:46 +02:00
parent 5c78356290
commit 9701e9c544
7 changed files with 69 additions and 31 deletions
+6 -4
View File
@@ -727,13 +727,15 @@ fn try_claim_multiple(
) -> Option<SiginfoAbi> {
while (proc_pending | thread_pending) & allowset != 0 {
let sig_idx = ((proc_pending | thread_pending) & allowset).trailing_zeros();
if thread_pending & (1 << sig_idx) != 0
if thread_pending & allowset & (1 << sig_idx) != 0
&& let Some(res) = try_claim_single(sig_idx, Some(control))
{
return Some(res);
}
thread_pending &= !(1 << sig_idx);
if let Some(res) = try_claim_single(sig_idx, None) {
if proc_pending & allowset & (1 << sig_idx) != 0
&& let Some(res) = try_claim_single(sig_idx, None)
{
return Some(res);
}
proc_pending &= !(1 << sig_idx);
@@ -741,7 +743,7 @@ fn try_claim_multiple(
None
}
fn try_claim_single(sig_idx: u32, thread_control: Option<&Sigcontrol>) -> Option<SiginfoAbi> {
let sig_group = sig_idx / 1;
let sig_group = sig_idx / 32;
if sig_group == 1 && thread_control.is_none() {
// Queued (realtime) signal
@@ -749,8 +751,8 @@ fn try_claim_single(sig_idx: u32, thread_control: Option<&Sigcontrol>) -> Option
let rt_inf = unsafe {
syscall::syscall2(
syscall::SYS_SIGDEQUEUE,
sig_idx as usize,
ret.as_mut_ptr() as usize,
sig_idx as usize - 32,
)
.ok()?;
ret.assume_init()
+7 -3
View File
@@ -142,7 +142,9 @@ pub unsafe extern "C" fn sigaction(
#[no_mangle]
pub unsafe extern "C" fn sigaddset(set: *mut sigset_t, signo: c_int) -> c_int {
if signo <= 0 || signo as usize > NSIG {
if signo <= 0 || signo as usize > NSIG.max(SIGRTMAX)
/* TODO */
{
platform::ERRNO.set(errno::EINVAL);
return -1;
}
@@ -162,7 +164,9 @@ pub unsafe extern "C" fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -
#[no_mangle]
pub unsafe extern "C" fn sigdelset(set: *mut sigset_t, signo: c_int) -> c_int {
if signo <= 0 || signo as usize > NSIG {
if signo <= 0 || signo as usize > NSIG.max(SIGRTMAX)
/* TODO */
{
platform::ERRNO.set(errno::EINVAL);
return -1;
}
@@ -379,7 +383,7 @@ pub unsafe extern "C" fn sigtimedwait(
sig: *mut siginfo, // https://github.com/mozilla/cbindgen/issues/621
tp: *const timespec,
) -> c_int {
Sys::sigtimedwait(&*set, &mut *sig, &*tp)
Sys::sigtimedwait(&*set, sig.as_mut(), &*tp)
.map(|()| 0)
.or_minus_one_errno()
}
+9 -4
View File
@@ -155,18 +155,23 @@ impl PalSignal for Sys {
.map(|_| ())
}
fn sigsuspend(set: &sigset_t) -> Errno {
fn sigsuspend(mask: &sigset_t) -> Errno {
unsafe {
e_raw(syscall!(RT_SIGSUSPEND, set as *const sigset_t, NSIG / 8)).expect_err("must fail")
e_raw(syscall!(RT_SIGSUSPEND, mask as *const sigset_t, NSIG / 8))
.expect_err("must fail")
}
}
fn sigtimedwait(set: &sigset_t, sig: &mut siginfo_t, tp: &timespec) -> Result<(), Errno> {
fn sigtimedwait(
set: &sigset_t,
sig: Option<&mut siginfo_t>,
tp: &timespec,
) -> Result<(), Errno> {
unsafe {
e_raw(syscall!(
RT_SIGTIMEDWAIT,
set as *const _,
sig as *mut _,
sig.map_or_else(core::ptr::null_mut, |s| s as *mut _) as usize,
tp as *const _,
NSIG / 8
))
+5 -1
View File
@@ -39,5 +39,9 @@ pub trait PalSignal: Pal {
fn sigsuspend(mask: &sigset_t) -> Errno; // always fails
fn sigtimedwait(set: &sigset_t, sig: &mut siginfo_t, tp: &timespec) -> Result<(), Errno>;
fn sigtimedwait(
set: &sigset_t,
sig: Option<&mut siginfo_t>,
tp: &timespec,
) -> Result<(), Errno>;
}
+5 -2
View File
@@ -273,7 +273,7 @@ impl PalSignal for Sys {
fn sigtimedwait(
set: &sigset_t,
info_out: &mut siginfo_t,
info_out: Option<&mut siginfo_t>,
timeout: &timespec,
) -> Result<(), Errno> {
// TODO: deadline-based API
@@ -281,7 +281,10 @@ impl PalSignal for Sys {
tv_sec: timeout.tv_sec,
tv_nsec: timeout.tv_nsec as _,
};
*info_out = redox_rt::signal::await_signal_sync(*set, &timeout)?.into();
let info = redox_rt::signal::await_signal_sync(*set, &timeout)?.into();
if let Some(out) = info_out {
*out = info;
}
Ok(())
}
}
+5
View File
@@ -23,14 +23,19 @@ void handler2(int sig, siginfo_t *info, void *context_raw) {
assert(info != NULL);
assert(info->si_signo == SIGUSR1);
#ifndef __linux
// TODO: SI_TKILL?
assert(info->si_code == SI_USER);
assert(info->si_pid == getpid());
assert(info->si_uid == getuid());
#endif
ucontext_t *context = context_raw;
assert(context != NULL);
#ifndef __linux__ // TODO
assert(memcmp(&context->uc_sigmask, &the_set, sizeof(sigset_t)));
assert(context->uc_link == NULL);
#endif
}
int main(void) {
+32 -17
View File
@@ -10,20 +10,24 @@
#define THE_SIG SIGRTMIN
volatile sig_atomic_t num = 1;
volatile sig_atomic_t num = 0;
int parent;
void action(int sig, siginfo_t *info, void *context) {
(void)context;
void validate(int sig, const siginfo_t *info) {
assert(sig == THE_SIG);
assert(info != NULL);
assert(context != NULL);
assert(info->si_signo == THE_SIG);
assert(info->si_value.sival_int == num);
assert(info->si_code == SI_QUEUE);
assert(info->si_pid == parent);
}
void action(int sig, siginfo_t *info, void *context) {
num++;
(void)context;
assert(context != NULL);
validate(sig, info);
write(1, "action\n", 7);
}
@@ -42,22 +46,27 @@ int main(void) {
status = close(fds[child == 0 ? 0 : 1]);
ERROR_IF(close, status, == -1);
sigset_t set;
status = sigfillset(&set);
sigset_t set, mask;
status = sigfillset(&mask);
ERROR_IF(sigfillset, status, == -1);
status = sigdelset(&set, SIGSEGV);
status = sigdelset(&mask, SIGSEGV);
ERROR_IF(sigdelset, status, == -1);
status = sigdelset(&set, SIGBUS);
status = sigdelset(&mask, SIGBUS);
ERROR_IF(sigdelset, status, == -1);
status = sigdelset(&set, SIGILL);
status = sigdelset(&mask, SIGILL);
ERROR_IF(sigdelset, status, == -1);
status = sigdelset(&set, SIGFPE);
status = sigdelset(&mask, SIGFPE);
ERROR_IF(sigdelset, status, == -1);
status = sigdelset(&set, SIGINT);
status = sigdelset(&mask, SIGINT);
ERROR_IF(sigdelset, status, == -1);
status = sigprocmask(SIG_SETMASK, &set, NULL);
status = sigprocmask(SIG_SETMASK, &mask, NULL);
ERROR_IF(sigprocmask, status, == -1);
status = sigemptyset(&set);
ERROR_IF(sigemptyset, status, == -1);
status = sigaddset(&set, THE_SIG);
ERROR_IF(sigaddset, status, == -1);
struct sigaction sa;
memcpy(&sa.sa_mask, &set, sizeof (sigset_t));
sa.sa_flags = SA_SIGINFO;
@@ -67,14 +76,20 @@ int main(void) {
ERROR_IF(sigaction, status, == -1);
if (child == 0) {
status = sigemptyset(&set);
ERROR_IF(sigemptyset, status, == -1);
while (num != 32) {
}
assert(num == 0);
siginfo_t info;
struct timespec t = (struct timespec){ .tv_sec = 1, .tv_nsec = 0 };
status = sigtimedwait(&set, &info, &t);
ERROR_IF(sigtimedwait, status, == -1);
validate(THE_SIG, &info);
assert(num == 0); // ensure no signal handler ran
while (num < 31) {}
status = write(fds[1], "A", 1);
ERROR_IF(write, status, == -1);
} else {
for (int n = 1; n <= 32; n++) {
for (int n = 0; n <= 31; n++) {
status = sigqueue(child, THE_SIG, (union sigval){ .sival_int = n });
ERROR_IF(sigqueue, status, == -1);
}