diff --git a/src/libos/src/net/syscalls.rs b/src/libos/src/net/syscalls.rs index eb4f49f8..fe02a6d4 100644 --- a/src/libos/src/net/syscalls.rs +++ b/src/libos/src/net/syscalls.rs @@ -7,8 +7,9 @@ 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 std::convert::TryFrom; -use time::timeval_t; +use time::{timespec_t, timeval_t}; use util::mem_util::from_user; pub fn do_socket(domain: c_int, socket_type: c_int, protocol: c_int) -> Result { @@ -714,7 +715,40 @@ pub fn do_select( ret } +pub fn do_ppoll( + fds: *mut libc::pollfd, + nfds: libc::nfds_t, + timeout_ts: *const timespec_t, + sigmask: *const sigset_t, +) -> Result { + let mut timeout = if timeout_ts.is_null() { + None + } else { + from_user::check_ptr(timeout_ts)?; + let timeout_ts = unsafe { &*timeout_ts }; + Some(timeout_ts.as_duration()) + }; + if !sigmask.is_null() { + warn!("ppoll sigmask is not supported!"); + } + do_poll_common(fds, nfds, timeout.as_mut(), None) +} + pub fn do_poll(fds: *mut libc::pollfd, nfds: libc::nfds_t, timeout_ms: c_int) -> Result { + let mut timeout = if timeout_ms >= 0 { + Some(Duration::from_millis(timeout_ms as u64)) + } else { + None + }; + do_poll_common(fds, nfds, timeout.as_mut(), None) +} + +fn do_poll_common( + fds: *mut libc::pollfd, + nfds: libc::nfds_t, + timeout: Option<&mut Duration>, + sigmask: Option, +) -> Result { // It behaves like sleep when fds is null and nfds is zero. if !fds.is_null() || nfds != 0 { from_user::check_mut_array(fds, nfds as usize)?; @@ -737,13 +771,7 @@ pub fn do_poll(fds: *mut libc::pollfd, nfds: libc::nfds_t, timeout_ms: c_int) -> .map(|raw| PollFd::from_raw(raw)) .collect(); - let mut timeout = if timeout_ms >= 0 { - Some(Duration::from_millis(timeout_ms as u64)) - } else { - None - }; - - let count = io_multiplexing::do_poll_new(&poll_fds, timeout.as_mut())?; + let count = io_multiplexing::do_poll_new(&poll_fds, timeout)?; for (raw_poll_fd, poll_fd) in raw_poll_fds.iter_mut().zip(poll_fds.iter()) { raw_poll_fd.revents = poll_fd.revents().get().to_raw() as i16; diff --git a/src/libos/src/syscall/mod.rs b/src/libos/src/syscall/mod.rs index d477cc9a..d71246de 100644 --- a/src/libos/src/syscall/mod.rs +++ b/src/libos/src/syscall/mod.rs @@ -38,8 +38,8 @@ 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_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_recvfrom, do_recvmsg, do_select, do_sendmmsg, do_sendmsg, do_sendto, + do_setsockopt, do_shutdown, do_socket, do_socketpair, mmsghdr, msghdr, msghdr_mut, }; use crate::process::{ do_arch_prctl, do_clone, do_execve, do_exit, do_exit_group, do_futex, do_get_robust_list, @@ -359,7 +359,7 @@ macro_rules! process_syscall_table_with_callback { (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(), - (Ppoll = 271) => handle_unsupported(), + (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), (GetRobustList = 274) => do_get_robust_list(tid: pid_t, list_head_ptr_ptr: *mut *mut RobustListHead, len_ptr: *mut usize),