Add syscall rt_sigpending

This commit is contained in:
anbo
2024-06-03 15:03:15 +08:00
committed by Tate, Hongliang Tian
parent 6c34db52b3
commit 901bccadfe
8 changed files with 167 additions and 5 deletions

View File

@ -8,8 +8,11 @@ use super::{
do_exit_group,
kill::SignalSenderIds,
signal::{
sig_mask::SigMask, sig_num::SigNum, sig_queues::SigQueues, signals::Signal, SigEvents,
SigEventsFilter, SigStack,
sig_mask::{SigMask, SigSet},
sig_num::SigNum,
sig_queues::SigQueues,
signals::Signal,
SigEvents, SigEventsFilter, SigStack,
},
Credentials, Process, TermStatus,
};
@ -82,6 +85,10 @@ impl PosixThread {
&self.sig_mask
}
pub fn sig_pending(&self) -> SigSet {
self.sig_queues.sig_pending()
}
pub fn has_pending_signal(&self) -> bool {
!self.sig_queues.is_empty()
}

View File

@ -3,9 +3,12 @@
use super::{constants::MIN_STD_SIG_NUM, sig_num::SigNum};
use crate::prelude::*;
/// A signal mask.
pub type SigMask = SigSet;
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Pod)]
#[repr(C)]
pub struct SigMask {
pub struct SigSet {
bits: u64,
}

View File

@ -3,7 +3,11 @@
use core::sync::atomic::{AtomicUsize, Ordering};
use super::{
constants::*, sig_mask::SigMask, sig_num::SigNum, signals::Signal, SigEvents, SigEventsFilter,
constants::*,
sig_mask::{SigMask, SigSet},
sig_num::SigNum,
signals::Signal,
SigEvents, SigEventsFilter,
};
use crate::{
events::{Observer, Subject},
@ -57,6 +61,11 @@ impl SigQueues {
signal
}
pub fn sig_pending(&self) -> SigSet {
let queues = self.queues.lock();
queues.sig_pending()
}
pub fn register_observer(
&self,
observer: Weak<dyn Observer<SigEvents>>,
@ -191,4 +200,24 @@ impl Queues {
let idx = (signum.as_u8() - MIN_RT_SIG_NUM) as usize;
&mut self.rt_queues[idx]
}
fn sig_pending(&self) -> SigSet {
let mut pending = SigSet::new_empty();
// Process standard signal queues
for (idx, signal) in self.std_queues.iter().enumerate() {
if signal.is_some() {
pending.add_signal(SigNum::from_u8(idx as u8 + MIN_STD_SIG_NUM));
}
}
// Process real-time signal queues
for (idx, signals) in self.rt_queues.iter().enumerate() {
if !signals.is_empty() {
pending.add_signal(SigNum::from_u8(idx as u8 + MIN_RT_SIG_NUM));
}
}
pending
}
}

View File

@ -69,6 +69,7 @@ use crate::syscall::{
rename::{sys_rename, sys_renameat},
rmdir::sys_rmdir,
rt_sigaction::sys_rt_sigaction,
rt_sigpending::sys_rt_sigpending,
rt_sigprocmask::sys_rt_sigprocmask,
rt_sigreturn::sys_rt_sigreturn,
rt_sigsuspend::sys_rt_sigsuspend,
@ -208,6 +209,7 @@ impl_syscall_nums_and_dispatch_fn! {
SYS_SETFSUID = 122 => sys_setfsuid(args[..1]);
SYS_SETFSGID = 123 => sys_setfsgid(args[..1]);
SYS_GETSID = 124 => sys_getsid(args[..1]);
SYS_RT_SIGPENDING = 127 => sys_rt_sigpending(args[..2]);
SYS_RT_SIGSUSPEND = 130 => sys_rt_sigsuspend(args[..2]);
SYS_SIGALTSTACK = 131 => sys_sigaltstack(args[..2]);
SYS_STATFS = 137 => sys_statfs(args[..2]);

View File

@ -76,6 +76,7 @@ mod recvfrom;
mod rename;
mod rmdir;
mod rt_sigaction;
mod rt_sigpending;
mod rt_sigprocmask;
mod rt_sigreturn;
mod rt_sigsuspend;

View File

@ -0,0 +1,30 @@
// SPDX-License-Identifier: MPL-2.0
use super::SyscallReturn;
use crate::{prelude::*, process::posix_thread::PosixThreadExt, util::write_val_to_user};
pub fn sys_rt_sigpending(u_set_ptr: Vaddr, sigset_size: usize) -> Result<SyscallReturn> {
debug!(
"u_set_ptr = 0x{:x}, sigset_size = {}",
u_set_ptr, sigset_size
);
if sigset_size != 8 {
return_errno_with_message!(Errno::EINVAL, "sigset size is not equal to 8")
}
do_rt_sigpending(u_set_ptr, sigset_size)?;
Ok(SyscallReturn::Return(0))
}
fn do_rt_sigpending(set_ptr: Vaddr, sigset_size: usize) -> Result<()> {
let current_thread = current_thread!();
let posix_thread = current_thread.as_posix_thread().unwrap();
let combined_signals = {
let sig_mask_value = posix_thread.sig_mask().lock().as_u64();
let sig_pending_value = posix_thread.sig_pending().as_u64();
sig_mask_value & sig_pending_value
};
write_val_to_user(set_ptr, &combined_signals)?;
Ok(())
}