From 0cb7a8f3130da47c8cd0ff5c6a035aa1f2b9e676 Mon Sep 17 00:00:00 2001 From: Haibo Huang Date: Tue, 5 Jan 2021 21:36:04 -0800 Subject: Upgrade rust/crates/mio to 0.7.7 Test: make Change-Id: Ie71fb1d573d92b099ad5a5b84fc1b92303aaa849 --- src/sys/shell/tcp.rs | 12 +++-------- src/sys/shell/udp.rs | 4 ++++ src/sys/unix/pipe.rs | 49 ++++++++++++++++++++++++++++++++++++++++++ src/sys/unix/udp.rs | 18 +++++++++++++++- src/sys/unix/uds/socketaddr.rs | 4 ++++ src/sys/unix/waker.rs | 6 ++++++ src/sys/windows/event.rs | 1 + src/sys/windows/udp.rs | 30 ++++++++++++++++++++++++-- 8 files changed, 112 insertions(+), 12 deletions(-) (limited to 'src/sys') diff --git a/src/sys/shell/tcp.rs b/src/sys/shell/tcp.rs index 2017bda..0ed225f 100644 --- a/src/sys/shell/tcp.rs +++ b/src/sys/shell/tcp.rs @@ -1,7 +1,7 @@ +use crate::net::TcpKeepalive; use std::io; use std::net::{self, SocketAddr}; use std::time::Duration; -use crate::net::TcpKeepalive; pub(crate) type TcpSocket = i32; @@ -79,24 +79,18 @@ pub(crate) fn get_keepalive(_: TcpSocket) -> io::Result { os_required!(); } -#[cfg(any( - target_os = "linux", - target_os = "macos", - target_os = "ios", - target_os = "freebsd", - target_os = "netbsd", - target_os = "windows", -))] pub(crate) fn set_keepalive_params(_: TcpSocket, _: TcpKeepalive) -> io::Result<()> { os_required!() } #[cfg(any( + target_os = "android", target_os = "linux", target_os = "macos", target_os = "ios", target_os = "freebsd", target_os = "netbsd", + target_os = "solaris", ))] pub(crate) fn get_keepalive_time(_: TcpSocket) -> io::Result> { os_required!() diff --git a/src/sys/shell/udp.rs b/src/sys/shell/udp.rs index 3ff1625..48ccac7 100644 --- a/src/sys/shell/udp.rs +++ b/src/sys/shell/udp.rs @@ -4,3 +4,7 @@ use std::net::{self, SocketAddr}; pub fn bind(_: SocketAddr) -> io::Result { os_required!() } + +pub(crate) fn only_v6(_: &net::UdpSocket) -> io::Result { + os_required!() +} diff --git a/src/sys/unix/pipe.rs b/src/sys/unix/pipe.rs index d838ebc..ccf5252 100644 --- a/src/sys/unix/pipe.rs +++ b/src/sys/unix/pipe.rs @@ -154,6 +154,7 @@ pub fn new() -> io::Result<(Sender, Receiver)> { target_os = "linux", target_os = "netbsd", target_os = "openbsd", + target_os = "illumos", ))] unsafe { if libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC | libc::O_NONBLOCK) != 0 { @@ -192,6 +193,7 @@ pub fn new() -> io::Result<(Sender, Receiver)> { target_os = "ios", target_os = "macos", target_os = "solaris", + target_os = "illumos", )))] compile_error!("unsupported target for `mio::unix::pipe`"); @@ -254,6 +256,20 @@ impl Write for Sender { } } +impl Write for &Sender { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.inner.do_io(|sender| (&*sender).write(buf)) + } + + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + self.inner.do_io(|sender| (&*sender).write_vectored(bufs)) + } + + fn flush(&mut self) -> io::Result<()> { + self.inner.do_io(|sender| (&*sender).flush()) + } +} + /// # Notes /// /// The underlying pipe is **not** set to non-blocking. @@ -333,6 +349,16 @@ impl Read for Receiver { } } +impl Read for &Receiver { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.inner.do_io(|sender| (&*sender).read(buf)) + } + + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + self.inner.do_io(|sender| (&*sender).read_vectored(bufs)) + } +} + /// # Notes /// /// The underlying pipe is **not** set to non-blocking. @@ -373,6 +399,7 @@ impl IntoRawFd for Receiver { } } +#[cfg(not(target_os = "illumos"))] fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> { let value = nonblocking as libc::c_int; if unsafe { libc::ioctl(fd, libc::FIONBIO, &value) } == -1 { @@ -381,3 +408,25 @@ fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> { Ok(()) } } + +#[cfg(target_os = "illumos")] +fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> { + let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) }; + if flags < 0 { + return Err(io::Error::last_os_error()); + } + + let nflags = if nonblocking { + flags | libc::O_NONBLOCK + } else { + flags & !libc::O_NONBLOCK + }; + + if flags != nflags { + if unsafe { libc::fcntl(fd, libc::F_SETFL, nflags) } < 0 { + return Err(io::Error::last_os_error()); + } + } + + Ok(()) +} diff --git a/src/sys/unix/udp.rs b/src/sys/unix/udp.rs index e9c4d4c..5a97cbd 100644 --- a/src/sys/unix/udp.rs +++ b/src/sys/unix/udp.rs @@ -1,8 +1,9 @@ use crate::sys::unix::net::{new_ip_socket, socket_addr}; use std::io; +use std::mem; use std::net::{self, SocketAddr}; -use std::os::unix::io::FromRawFd; +use std::os::unix::io::{AsRawFd, FromRawFd}; pub fn bind(addr: SocketAddr) -> io::Result { // Gives a warning for non Apple platforms. @@ -21,3 +22,18 @@ pub fn bind(addr: SocketAddr) -> io::Result { .map(|_| unsafe { net::UdpSocket::from_raw_fd(socket) }) }) } + +pub(crate) fn only_v6(socket: &net::UdpSocket) -> io::Result { + let mut optval: libc::c_int = 0; + let mut optlen = mem::size_of::() as libc::socklen_t; + + syscall!(getsockopt( + socket.as_raw_fd(), + libc::IPPROTO_IPV6, + libc::IPV6_V6ONLY, + &mut optval as *mut _ as *mut _, + &mut optlen, + ))?; + + Ok(optval != 0) +} diff --git a/src/sys/unix/uds/socketaddr.rs b/src/sys/unix/uds/socketaddr.rs index 31f8a51..a9f9ea9 100644 --- a/src/sys/unix/uds/socketaddr.rs +++ b/src/sys/unix/uds/socketaddr.rs @@ -28,6 +28,10 @@ enum AddressKind<'a> { impl SocketAddr { fn address(&self) -> AddressKind<'_> { let offset = path_offset(&self.sockaddr); + // Don't underflow in `len` below. + if (self.socklen as usize) < offset { + return AddressKind::Unnamed; + } let len = self.socklen as usize - offset; let path = unsafe { &*(&self.sockaddr.sun_path as *const [libc::c_char] as *const [u8]) }; diff --git a/src/sys/unix/waker.rs b/src/sys/unix/waker.rs index 1305bd6..a7cf484 100644 --- a/src/sys/unix/waker.rs +++ b/src/sys/unix/waker.rs @@ -137,6 +137,12 @@ mod pipe { } pub fn wake(&self) -> io::Result<()> { + // The epoll emulation on some illumos systems currently requires + // the pipe buffer to be completely empty for an edge-triggered + // wakeup on the pipe read side. + #[cfg(target_os = "illumos")] + self.empty(); + match (&self.sender).write(&[1]) { Ok(_) => Ok(()), Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => { diff --git a/src/sys/windows/event.rs b/src/sys/windows/event.rs index 4d04e64..a49252a 100644 --- a/src/sys/windows/event.rs +++ b/src/sys/windows/event.rs @@ -5,6 +5,7 @@ use miow::iocp::CompletionStatus; use super::afd; use crate::Token; +#[derive(Clone)] pub struct Event { pub flags: u32, pub data: u64, diff --git a/src/sys/windows/udp.rs b/src/sys/windows/udp.rs index ba2aeac..825eccc 100644 --- a/src/sys/windows/udp.rs +++ b/src/sys/windows/udp.rs @@ -1,9 +1,13 @@ use std::io; +use std::mem::{self, MaybeUninit}; use std::net::{self, SocketAddr}; -use std::os::windows::io::FromRawSocket; +use std::os::windows::io::{AsRawSocket, FromRawSocket}; use std::os::windows::raw::SOCKET as StdSocket; // winapi uses usize, stdlib uses u32/u64. -use winapi::um::winsock2::{bind as win_bind, closesocket, SOCKET_ERROR, SOCK_DGRAM}; +use winapi::ctypes::c_int; +use winapi::shared::ws2def::IPPROTO_IPV6; +use winapi::shared::ws2ipdef::IPV6_V6ONLY; +use winapi::um::winsock2::{bind as win_bind, closesocket, getsockopt, SOCKET_ERROR, SOCK_DGRAM}; use crate::sys::windows::net::{init, new_ip_socket, socket_addr}; @@ -25,3 +29,25 @@ pub fn bind(addr: SocketAddr) -> io::Result { .map(|_| unsafe { net::UdpSocket::from_raw_socket(socket as StdSocket) }) }) } + +pub(crate) fn only_v6(socket: &net::UdpSocket) -> io::Result { + let mut optval: MaybeUninit = MaybeUninit::uninit(); + let mut optlen = mem::size_of::() as c_int; + + syscall!( + getsockopt( + socket.as_raw_socket() as usize, + IPPROTO_IPV6 as c_int, + IPV6_V6ONLY as c_int, + optval.as_mut_ptr().cast(), + &mut optlen, + ), + PartialEq::eq, + SOCKET_ERROR + )?; + + debug_assert_eq!(optlen as usize, mem::size_of::()); + // Safety: `getsockopt` initialised `optval` for us. + let optval = unsafe { optval.assume_init() }; + Ok(optval != 0) +} -- cgit v1.2.3