[libos] Implement Pselect syscall with sigset
This commit is contained in:
		
							parent
							
								
									4d2ba8ca01
								
							
						
					
					
						commit
						56528f67da
					
				| @ -7,7 +7,7 @@ use super::io_multiplexing::{AsEpollFile, EpollCtl, EpollFile, EpollFlags, FdSet | ||||
| use fs::{CreationFlags, File, FileDesc, FileRef}; | ||||
| use misc::resource_t; | ||||
| use process::Process; | ||||
| use signal::{sigset_t, SigSet}; | ||||
| use signal::{do_sigprocmask, sigset_t, MaskOp, SigSet}; | ||||
| use std::convert::TryFrom; | ||||
| use time::{timespec_t, timeval_t}; | ||||
| use util::mem_util::from_user; | ||||
| @ -723,6 +723,109 @@ pub fn do_select( | ||||
|     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( | ||||
|     fds: *mut libc::pollfd, | ||||
|     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::constants::*; | ||||
| 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::sig_dispositions::SigDispositions; | ||||
| pub use self::sig_num::SigNum; | ||||
| @ -21,7 +22,6 @@ mod do_kill; | ||||
| mod do_sigaction; | ||||
| mod do_sigaltstack; | ||||
| mod do_sigpending; | ||||
| mod do_sigprocmask; | ||||
| mod do_sigreturn; | ||||
| mod do_sigtimedwait; | ||||
| mod sig_action; | ||||
| @ -34,3 +34,4 @@ mod signals; | ||||
| mod syscalls; | ||||
| 
 | ||||
| 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::{ | ||||
|     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_poll, do_ppoll, do_recvfrom, do_recvmsg, do_select, do_sendmmsg, do_sendmsg, do_sendto, | ||||
|     do_setsockopt, do_shutdown, do_socket, do_socketpair, mmsghdr, msghdr, msghdr_mut, | ||||
|     do_poll, do_ppoll, do_pselect6, do_recvfrom, do_recvmsg, do_select, do_sendmmsg, do_sendmsg, | ||||
|     do_sendto, do_setsockopt, do_shutdown, do_socket, do_socketpair, mmsghdr, msghdr, msghdr_mut, | ||||
|     Pselect6sig, | ||||
| }; | ||||
| use crate::process::{ | ||||
|     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), | ||||
|             (Fchmodat = 268) => do_fchmodat(dirfd: i32, path: *const i8, mode: u16), | ||||
|             (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), | ||||
|             (Unshare = 272) => handle_unsupported(), | ||||
|             (SetRobustList = 273) => do_set_robust_list(list_head_ptr: *mut RobustListHead, len: usize), | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user