aboutsummaryrefslogtreecommitdiff
path: root/src/sys/unix
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/unix
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/unix')
-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
4 files changed, 76 insertions, 1 deletions
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 => {