mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-10 13:56:48 +00:00
Add gvisor pselect test
This commit is contained in:
parent
8b73cc8761
commit
dc124351d2
@ -54,7 +54,7 @@ fn do_clock_nanosleep(
|
||||
) -> Result<SyscallReturn> {
|
||||
let request_time = {
|
||||
let timespec = read_val_from_user::<timespec_t>(request_timespec_addr)?;
|
||||
Duration::from(timespec)
|
||||
Duration::try_from(timespec)?
|
||||
};
|
||||
|
||||
debug!(
|
||||
|
@ -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>()
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,23 @@ pub fn sys_select(
|
||||
writefds_addr: Vaddr,
|
||||
exceptfds_addr: Vaddr,
|
||||
timeval_addr: Vaddr,
|
||||
) -> Result<SyscallReturn> {
|
||||
let timeout = if timeval_addr == 0 {
|
||||
None
|
||||
} else {
|
||||
let timeval = read_val_from_user::<timeval_t>(timeval_addr)?;
|
||||
Some(Duration::from(timeval))
|
||||
};
|
||||
|
||||
do_sys_select(nfds, readfds_addr, writefds_addr, exceptfds_addr, timeout)
|
||||
}
|
||||
|
||||
pub fn do_sys_select(
|
||||
nfds: FileDesc,
|
||||
readfds_addr: Vaddr,
|
||||
writefds_addr: Vaddr,
|
||||
exceptfds_addr: Vaddr,
|
||||
timeout: Option<Duration>,
|
||||
) -> Result<SyscallReturn> {
|
||||
if nfds < 0 || nfds as usize > FD_SETSIZE {
|
||||
return_errno_with_message!(Errno::EINVAL, "nfds is negative or exceeds the FD_SETSIZE");
|
||||
@ -40,13 +57,6 @@ pub fn sys_select(
|
||||
let mut writefds = get_fdset(writefds_addr)?;
|
||||
let mut exceptfds = get_fdset(exceptfds_addr)?;
|
||||
|
||||
let timeout = if timeval_addr == 0 {
|
||||
None
|
||||
} else {
|
||||
let timeval = read_val_from_user::<timeval_t>(timeval_addr)?;
|
||||
Some(Duration::from(timeval))
|
||||
};
|
||||
|
||||
debug!(
|
||||
"nfds = {}, readfds = {:?}, writefds = {:?}, exceptfds = {:?}, timeout = {:?}",
|
||||
nfds, readfds, writefds, exceptfds, timeout
|
||||
|
@ -20,8 +20,8 @@ pub fn sys_timer_settime(
|
||||
}
|
||||
|
||||
let new_itimerspec = read_val_from_user::<itimerspec_t>(new_itimerspec_addr)?;
|
||||
let interval = Duration::from(new_itimerspec.it_interval);
|
||||
let expire_time = Duration::from(new_itimerspec.it_value);
|
||||
let interval = Duration::try_from(new_itimerspec.it_interval)?;
|
||||
let expire_time = Duration::try_from(new_itimerspec.it_value)?;
|
||||
|
||||
let current_process = current!();
|
||||
let Some(timer) = current_process.timer_manager().find_posix_timer(timer_id) else {
|
||||
|
@ -120,14 +120,14 @@ fn vfs_utimes(dentry: &Arc<Dentry>, times: Option<TimeSpecPair>) -> Result<Sysca
|
||||
} else if times.atime.is_utime_now() {
|
||||
now
|
||||
} else {
|
||||
Duration::from(times.atime)
|
||||
Duration::try_from(times.atime)?
|
||||
};
|
||||
let mtime = if times.mtime.is_utime_omit() {
|
||||
dentry.mtime()
|
||||
} else if times.mtime.is_utime_now() {
|
||||
now
|
||||
} else {
|
||||
Duration::from(times.mtime)
|
||||
Duration::try_from(times.mtime)?
|
||||
};
|
||||
(atime, mtime, now)
|
||||
}
|
||||
|
@ -52,9 +52,21 @@ impl From<timeval_t> for timespec_t {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<timespec_t> for Duration {
|
||||
fn from(timespec: timespec_t) -> Self {
|
||||
Duration::new(timespec.sec as u64, timespec.nsec as u32)
|
||||
impl TryFrom<timespec_t> for Duration {
|
||||
type Error = crate::Error;
|
||||
|
||||
fn try_from(value: timespec_t) -> Result<Self> {
|
||||
if value.sec < 0 || value.nsec < 0 {
|
||||
return_errno_with_message!(Errno::EINVAL, "timesepc_t cannot be negative");
|
||||
}
|
||||
|
||||
if value.nsec > 1_000_000_000 {
|
||||
// The value of nanoseconds cannot exceed 10^9,
|
||||
// otherwise the value for seconds should be set.
|
||||
return_errno_with_message!(Errno::EINVAL, "nsec is not normalized");
|
||||
}
|
||||
|
||||
Ok(Duration::new(value.sec as u64, value.nsec as u32))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ TESTS ?= \
|
||||
open_test \
|
||||
pread64_test \
|
||||
preadv2_test \
|
||||
pselect_test \
|
||||
pwrite64_test \
|
||||
pwritev2_test \
|
||||
pty_test \
|
||||
|
4
test/syscall_test/blocklists/pselect_test
Normal file
4
test/syscall_test/blocklists/pselect_test
Normal file
@ -0,0 +1,4 @@
|
||||
PselectTest.NoTimeout_NoRandomSave
|
||||
PselectTest.NullFds
|
||||
PselectTest.SignalMaskBlocksSignal
|
||||
PselectTest.SignalMaskAllowsSignal
|
Loading…
x
Reference in New Issue
Block a user