mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-18 12:06:43 +00:00
Add syscall rt_sigpending
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
6c34db52b3
commit
901bccadfe
@ -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()
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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]);
|
||||
|
@ -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;
|
||||
|
30
kernel/aster-nix/src/syscall/rt_sigpending.rs
Normal file
30
kernel/aster-nix/src/syscall/rt_sigpending.rs
Normal 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(())
|
||||
}
|
Reference in New Issue
Block a user