diff options
author | Haibo Huang <hhb@google.com> | 2021-01-05 21:36:04 -0800 |
---|---|---|
committer | Haibo Huang <hhb@google.com> | 2021-01-05 21:36:04 -0800 |
commit | 0cb7a8f3130da47c8cd0ff5c6a035aa1f2b9e676 (patch) | |
tree | a101b157e865fd1669dc9e122b0adddb7ce94978 /src/sys/unix | |
parent | 0fae4327dd02e0c99bff26c94ccacadb2ba83716 (diff) | |
download | mio-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.rs | 49 | ||||
-rw-r--r-- | src/sys/unix/udp.rs | 18 | ||||
-rw-r--r-- | src/sys/unix/uds/socketaddr.rs | 4 | ||||
-rw-r--r-- | src/sys/unix/waker.rs | 6 |
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 => { |