[libos] Implement Pselect syscall with sigset

This commit is contained in:
ClawSeven 2023-12-19 15:58:38 +08:00 committed by volcano
parent 4d2ba8ca01
commit 56528f67da
3 changed files with 110 additions and 5 deletions

@ -7,7 +7,7 @@ use super::io_multiplexing::{AsEpollFile, EpollCtl, EpollFile, EpollFlags, FdSet
use fs::{CreationFlags, File, FileDesc, FileRef}; use fs::{CreationFlags, File, FileDesc, FileRef};
use misc::resource_t; use misc::resource_t;
use process::Process; use process::Process;
use signal::{sigset_t, SigSet}; use signal::{do_sigprocmask, sigset_t, MaskOp, SigSet};
use std::convert::TryFrom; use std::convert::TryFrom;
use time::{timespec_t, timeval_t}; use time::{timespec_t, timeval_t};
use util::mem_util::from_user; use util::mem_util::from_user;
@ -723,6 +723,109 @@ pub fn do_select(
ret ret
} }
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct Pselect6sig {
ss: *const sigset_t,
ss_len: size_t,
}
pub fn do_pselect6(
nfds: c_int,
readfds: *mut libc::fd_set,
writefds: *mut libc::fd_set,
exceptfds: *mut libc::fd_set,
timeout: *mut timespec_t,
sig_data: *const Pselect6sig,
) -> Result<isize> {
let mut is_set_sig = false;
let mut original_sig_set = sigset_t::default();
if !sig_data.is_null() {
from_user::check_ptr(sig_data)?;
let user_sig_data = unsafe { &*(sig_data) };
is_set_sig = !user_sig_data.ss.is_null();
if is_set_sig {
if user_sig_data.ss_len != std::mem::size_of::<sigset_t>() {
return_errno!(EINVAL, "unexpected sigset size");
}
let op_and_set = {
let op = MaskOp::SetMask;
let sigset = user_sig_data.ss;
from_user::check_ptr(sigset)?;
let set = unsafe { &*sigset };
Some((op, set))
};
do_sigprocmask::do_rt_sigprocmask(op_and_set, Some(&mut original_sig_set))?;
}
}
let nfds = {
let soft_rlimit_nofile = current!()
.rlimits()
.lock()
.unwrap()
.get(resource_t::RLIMIT_NOFILE)
.get_cur();
if nfds < 0 || nfds > libc::FD_SETSIZE as i32 || nfds as u64 > soft_rlimit_nofile {
return_errno!(
EINVAL,
"nfds is negative or exceeds the resource limit or FD_SETSIZE"
);
}
nfds as FileDesc
};
let mut timeout_c = if !timeout.is_null() {
from_user::check_ptr(timeout)?;
let timeval = unsafe { &mut *timeout };
timeval.validate()?;
Some(timeval)
} else {
None
};
let mut timeout = timeout_c.as_ref().map(|timeout_c| timeout_c.as_duration());
let readfds = if !readfds.is_null() {
from_user::check_mut_ptr(readfds)?;
Some(unsafe { &mut *readfds })
} else {
None
};
let writefds = if !writefds.is_null() {
from_user::check_mut_ptr(writefds)?;
Some(unsafe { &mut *writefds })
} else {
None
};
let exceptfds = if !exceptfds.is_null() {
from_user::check_mut_ptr(exceptfds)?;
Some(unsafe { &mut *exceptfds })
} else {
None
};
let ret = io_multiplexing::do_select(nfds, readfds, writefds, exceptfds, timeout.as_mut());
if let Some(timeout_c) = timeout_c {
*timeout_c = timeout.unwrap().into();
}
// Restore the original signal mask
if is_set_sig {
let op_and_set = {
let op = MaskOp::SetMask;
let set = &original_sig_set;
Some((op, set))
};
do_sigprocmask::do_rt_sigprocmask(op_and_set, None)?;
}
ret
}
pub fn do_ppoll( pub fn do_ppoll(
fds: *mut libc::pollfd, fds: *mut libc::pollfd,
nfds: libc::nfds_t, nfds: libc::nfds_t,

@ -7,6 +7,7 @@ use sig_action::{SigAction, SigActionFlags, SigDefaultAction};
pub use self::c_types::{sigaction_t, siginfo_t, sigset_t, stack_t}; pub use self::c_types::{sigaction_t, siginfo_t, sigset_t, stack_t};
pub use self::constants::*; pub use self::constants::*;
pub use self::do_kill::do_kill_from_outside_enclave; pub use self::do_kill::do_kill_from_outside_enclave;
pub use self::do_sigprocmask::MaskOp;
pub use self::do_sigreturn::{deliver_signal, force_signal}; pub use self::do_sigreturn::{deliver_signal, force_signal};
pub use self::sig_dispositions::SigDispositions; pub use self::sig_dispositions::SigDispositions;
pub use self::sig_num::SigNum; pub use self::sig_num::SigNum;
@ -21,7 +22,6 @@ mod do_kill;
mod do_sigaction; mod do_sigaction;
mod do_sigaltstack; mod do_sigaltstack;
mod do_sigpending; mod do_sigpending;
mod do_sigprocmask;
mod do_sigreturn; mod do_sigreturn;
mod do_sigtimedwait; mod do_sigtimedwait;
mod sig_action; mod sig_action;
@ -34,3 +34,4 @@ mod signals;
mod syscalls; mod syscalls;
pub mod constants; pub mod constants;
pub mod do_sigprocmask;

@ -43,8 +43,9 @@ use crate::misc::{resource_t, rlimit_t, sysinfo_t, utsname_t, RandFlags};
use crate::net::{ use crate::net::{
do_accept, do_accept4, do_bind, do_connect, do_epoll_create, do_epoll_create1, do_epoll_ctl, do_accept, do_accept4, do_bind, do_connect, do_epoll_create, do_epoll_create1, do_epoll_ctl,
do_epoll_pwait, do_epoll_wait, do_getpeername, do_getsockname, do_getsockopt, do_listen, do_epoll_pwait, do_epoll_wait, do_getpeername, do_getsockname, do_getsockopt, do_listen,
do_poll, do_ppoll, do_recvfrom, do_recvmsg, do_select, do_sendmmsg, do_sendmsg, do_sendto, do_poll, do_ppoll, do_pselect6, do_recvfrom, do_recvmsg, do_select, do_sendmmsg, do_sendmsg,
do_setsockopt, do_shutdown, do_socket, do_socketpair, mmsghdr, msghdr, msghdr_mut, do_sendto, do_setsockopt, do_shutdown, do_socket, do_socketpair, mmsghdr, msghdr, msghdr_mut,
Pselect6sig,
}; };
use crate::process::{ use crate::process::{
do_arch_prctl, do_clone, do_execve, do_exit, do_exit_group, do_futex, do_get_robust_list, do_arch_prctl, do_clone, do_execve, do_exit, do_exit_group, do_futex, do_get_robust_list,
@ -366,7 +367,7 @@ macro_rules! process_syscall_table_with_callback {
(Readlinkat = 267) => do_readlinkat(dirfd: i32, path: *const i8, buf: *mut u8, size: usize), (Readlinkat = 267) => do_readlinkat(dirfd: i32, path: *const i8, buf: *mut u8, size: usize),
(Fchmodat = 268) => do_fchmodat(dirfd: i32, path: *const i8, mode: u16), (Fchmodat = 268) => do_fchmodat(dirfd: i32, path: *const i8, mode: u16),
(Faccessat = 269) => do_faccessat(dirfd: i32, path: *const i8, mode: u32, flags: u32), (Faccessat = 269) => do_faccessat(dirfd: i32, path: *const i8, mode: u32, flags: u32),
(Pselect6 = 270) => handle_unsupported(), (Pselect6 = 270) => do_pselect6(nfds: c_int, readfds: *mut libc::fd_set, writefds: *mut libc::fd_set, exceptfds: *mut libc::fd_set, timeout: *mut timespec_t, data: *const Pselect6sig),
(Ppoll = 271) => do_ppoll(fds: *mut libc::pollfd, nfds: libc::nfds_t, timeout_ts: *const timespec_t, sigmask: *const sigset_t), (Ppoll = 271) => do_ppoll(fds: *mut libc::pollfd, nfds: libc::nfds_t, timeout_ts: *const timespec_t, sigmask: *const sigset_t),
(Unshare = 272) => handle_unsupported(), (Unshare = 272) => handle_unsupported(),
(SetRobustList = 273) => do_set_robust_list(list_head_ptr: *mut RobustListHead, len: usize), (SetRobustList = 273) => do_set_robust_list(list_head_ptr: *mut RobustListHead, len: usize),