aboutsummaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2021-01-05 21:36:04 -0800
committerHaibo Huang <hhb@google.com>2021-01-05 21:36:04 -0800
commit0cb7a8f3130da47c8cd0ff5c6a035aa1f2b9e676 (patch)
treea101b157e865fd1669dc9e122b0adddb7ce94978 /src/sys
parent0fae4327dd02e0c99bff26c94ccacadb2ba83716 (diff)
downloadmio-0cb7a8f3130da47c8cd0ff5c6a035aa1f2b9e676.tar.gz
Upgrade rust/crates/mio to 0.7.7platform-tools-31.0.0
Test: make Change-Id: Ie71fb1d573d92b099ad5a5b84fc1b92303aaa849
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/shell/tcp.rs12
-rw-r--r--src/sys/shell/udp.rs4
-rw-r--r--src/sys/unix/pipe.rs49
-rw-r--r--src/sys/unix/udp.rs18
-rw-r--r--src/sys/unix/uds/socketaddr.rs4
-rw-r--r--src/sys/unix/waker.rs6
-rw-r--r--src/sys/windows/event.rs1
-rw-r--r--src/sys/windows/udp.rs30
8 files changed, 112 insertions, 12 deletions
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<bool> {
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<Option<Duration>> {
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<net::UdpSocket> {
os_required!()
}
+
+pub(crate) fn only_v6(_: &net::UdpSocket) -> io::Result<bool> {
+ 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<usize> {
+ self.inner.do_io(|sender| (&*sender).write(buf))
+ }
+
+ fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+ 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<usize> {
+ self.inner.do_io(|sender| (&*sender).read(buf))
+ }
+
+ fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+ 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<net::UdpSocket> {
// Gives a warning for non Apple platforms.
@@ -21,3 +22,18 @@ pub fn bind(addr: SocketAddr) -> io::Result<net::UdpSocket> {
.map(|_| unsafe { net::UdpSocket::from_raw_fd(socket) })
})
}
+
+pub(crate) fn only_v6(socket: &net::UdpSocket) -> io::Result<bool> {
+ let mut optval: libc::c_int = 0;
+ let mut optlen = mem::size_of::<libc::c_int>() 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<net::UdpSocket> {
.map(|_| unsafe { net::UdpSocket::from_raw_socket(socket as StdSocket) })
})
}
+
+pub(crate) fn only_v6(socket: &net::UdpSocket) -> io::Result<bool> {
+ let mut optval: MaybeUninit<c_int> = MaybeUninit::uninit();
+ let mut optlen = mem::size_of::<c_int>() 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::<c_int>());
+ // Safety: `getsockopt` initialised `optval` for us.
+ let optval = unsafe { optval.assume_init() };
+ Ok(optval != 0)
+}