Add gvisor pselect test

This commit is contained in:
Jianfeng Jiang
2024-08-09 03:53:32 +00:00
committed by Tate, Hongliang Tian
parent 8b73cc8761
commit dc124351d2
8 changed files with 75 additions and 27 deletions

View File

@ -1,12 +1,13 @@
// SPDX-License-Identifier: MPL-2.0
use core::sync::atomic::Ordering;
use core::{sync::atomic::Ordering, time::Duration};
use super::{select::sys_select, SyscallReturn};
use super::{select::do_sys_select, SyscallReturn};
use crate::{
fs::file_table::FileDesc,
prelude::*,
process::{posix_thread::PosixThreadExt, signal::sig_mask::SigMask},
time::timespec_t,
util::read_val_from_user,
};
@ -15,28 +16,35 @@ pub fn sys_pselect6(
readfds_addr: Vaddr,
writefds_addr: Vaddr,
exceptfds_addr: Vaddr,
timeval_addr: Vaddr,
timespec_addr: Vaddr,
sigmask_addr: Vaddr,
) -> Result<SyscallReturn> {
let current_thread = current_thread!();
let posix_thread = current_thread.as_posix_thread().unwrap();
let old_simask = if sigmask_addr != 0 {
let new_sigmask: SigMask = read_val_from_user(sigmask_addr)?;
let old_sigmask = posix_thread.sig_mask().swap(new_sigmask, Ordering::Relaxed);
let sigmask_with_size: SigMaskWithSize = read_val_from_user(sigmask_addr)?;
if !sigmask_with_size.is_valid() {
return_errno_with_message!(Errno::EINVAL, "sigmask size is invalid")
}
let old_sigmask = posix_thread
.sig_mask()
.swap(sigmask_with_size.sigmask, Ordering::Relaxed);
Some(old_sigmask)
} else {
None
};
let res = sys_select(
nfds,
readfds_addr,
writefds_addr,
exceptfds_addr,
timeval_addr,
);
let timeout = if timespec_addr != 0 {
let time_spec: timespec_t = read_val_from_user(timespec_addr)?;
Some(Duration::try_from(time_spec)?)
} else {
None
};
let res = do_sys_select(nfds, readfds_addr, writefds_addr, exceptfds_addr, timeout);
if let Some(old_mask) = old_simask {
posix_thread.sig_mask().store(old_mask, Ordering::Relaxed);
@ -44,3 +52,16 @@ pub fn sys_pselect6(
res
}
#[repr(C)]
#[derive(Debug, Clone, Copy, Pod)]
struct SigMaskWithSize {
sigmask: SigMask,
sigmasksize: usize,
}
impl SigMaskWithSize {
const fn is_valid(&self) -> bool {
self.sigmask.is_empty() || self.sigmasksize == size_of::<SigMask>()
}
}