Add syscall rt_sigsuspend

This commit is contained in:
Jianfeng Jiang
2023-12-04 09:22:47 +00:00
committed by Tate, Hongliang Tian
parent 25b7007ffa
commit 89b21ba3b4
4 changed files with 50 additions and 2 deletions

View File

@ -150,7 +150,7 @@ provided by Linux on x86-64 architecture.
| 127 | rt_sigpending | ❌ |
| 128 | rt_sigtimedwait | ❌ |
| 129 | rt_sigqueueinfo | ❌ |
| 130 | rt_sigsuspend | |
| 130 | rt_sigsuspend | |
| 131 | sigaltstack | ✅ |
| 132 | utime | ❌ |
| 133 | mknod | ❌ |

View File

@ -1,8 +1,10 @@
// SPDX-License-Identifier: MPL-2.0
use super::{constants::MIN_STD_SIG_NUM, sig_num::SigNum};
use crate::prelude::*;
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Pod)]
#[repr(C)]
pub struct SigMask {
bits: u64,
}

View File

@ -22,6 +22,7 @@ use self::{
listen::sys_listen,
pread64::sys_pread64,
recvfrom::sys_recvfrom,
rt_sigsuspend::sys_rt_sigsuspend,
sendto::sys_sendto,
setfsgid::sys_setfsgid,
setfsuid::sys_setfsuid,
@ -191,6 +192,7 @@ mod rmdir;
mod rt_sigaction;
mod rt_sigprocmask;
mod rt_sigreturn;
mod rt_sigsuspend;
mod sched_yield;
mod select;
mod sendto;
@ -352,6 +354,7 @@ define_syscall_nums!(
SYS_SETFSUID = 122,
SYS_SETFSGID = 123,
SYS_GETSID = 124,
SYS_RT_SIGSUSPEND = 130,
SYS_SIGALTSTACK = 131,
SYS_STATFS = 137,
SYS_FSTATFS = 138,
@ -544,6 +547,7 @@ pub fn syscall_dispatch(
SYS_SETFSUID => syscall_handler!(1, sys_setfsuid, args),
SYS_SETFSGID => syscall_handler!(1, sys_setfsgid, args),
SYS_GETSID => syscall_handler!(1, sys_getsid, args),
SYS_RT_SIGSUSPEND => syscall_handler!(2, sys_rt_sigsuspend, args),
SYS_SIGALTSTACK => syscall_handler!(2, sys_sigaltstack, args),
SYS_STATFS => syscall_handler!(2, sys_statfs, args),
SYS_FSTATFS => syscall_handler!(2, sys_fstatfs, args),

View File

@ -0,0 +1,42 @@
// SPDX-License-Identifier: MPL-2.0
use super::{SyscallReturn, SYS_RT_SIGSUSPEND};
use crate::{
log_syscall_entry,
prelude::*,
process::signal::{
constants::{SIGKILL, SIGSTOP},
sig_mask::SigMask,
Pauser,
},
util::read_val_from_user,
};
pub fn sys_rt_sigsuspend(sigmask_addr: Vaddr, sigmask_size: usize) -> Result<SyscallReturn> {
log_syscall_entry!(SYS_RT_SIGSUSPEND);
debug!(
"sigmask_addr = 0x{:x}, sigmask_size = {}",
sigmask_addr, sigmask_size
);
debug_assert!(sigmask_size == core::mem::size_of::<SigMask>());
if sigmask_size != core::mem::size_of::<SigMask>() {
return_errno_with_message!(Errno::EINVAL, "invalid sigmask size");
}
let sigmask = {
let mut mask: SigMask = read_val_from_user(sigmask_addr)?;
// It is not possible to block SIGKILL or SIGSTOP,
// specifying these signals in mask has no effect.
mask.remove_signal(SIGKILL);
mask.remove_signal(SIGSTOP);
mask
};
// Pause until receiving any signal
let pauser = Pauser::new_with_mask(sigmask);
pauser.pause_until(|| None::<()>)?;
// This syscall should always return `Err(EINTR)`. This path should never be reached.
unreachable!("rt_sigsuspend always return EINTR");
}