[libos] Implement Pselect syscall with sigset
This commit is contained in:
parent
976135b79c
commit
d27f0d5cd0
@ -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),
|
||||||
|
Loading…
Reference in New Issue
Block a user