Upgrade rust/crates/mio to 0.7.7

Test: make
Change-Id: Ie71fb1d573d92b099ad5a5b84fc1b92303aaa849
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 7fefbd3..5454293 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "e6e403fe2a4fc14dfbc74dbb3ae3a14e3044eb6f"
+    "sha1": "0fef0d61ade20be45eb670eb3786af0e06e59f63"
   }
 }
diff --git a/Android.bp b/Android.bp
index 825e135..6cc4e23 100644
--- a/Android.bp
+++ b/Android.bp
@@ -28,5 +28,5 @@
 
 // dependent_library ["feature_list"]
 //   cfg-if-0.1.10
-//   libc-0.2.80 "align,default,std"
+//   libc-0.2.81 "align,default,std"
 //   log-0.4.11 "std"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f024bfb..9e5059c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,33 @@
+# 0.7.7
+
+## Added
+
+* `UdpSocket::only_v6`
+  (https://github.com/tokio-rs/mio/commit/0101e05a800f17fb88f4315d9b9fe0f08cca6e57).
+* `Clone` implementation for `Event`
+  (https://github.com/tokio-rs/mio/commit/26540ebbae89df6d4d08465c56f715d8f2addfc3).
+* `AsRawFd` implementation for `Registry`
+  (https://github.com/tokio-rs/mio/commit/f70daa72da0042b1880256164774c3286d315a02).
+* `Read` and `Write` implementation for `&unix::pipe::Sender` and `Receiver`,
+  that is on the reference to them, an implementation existed on the types
+  themselves already
+  (https://github.com/tokio-rs/mio/commit/1be481dcbbcb6906364008b5d61e7f53cddc3eb3).
+
+
+## Fixes
+
+* Underflow in `SocketAddr::address`
+  (https://github.com/tokio-rs/mio/commit/6d3fa69240cd4bb95e9d34605c660c30245a18bd).
+* Android build with the net feature enabled, but with os-poll disabled
+  (https://github.com/tokio-rs/mio/commit/49d8fd33e026ad6e2c055d05d6667180ba2af7be).
+* Solaris build with the net feature enabled, but with os-poll disabled
+  (https://github.com/tokio-rs/mio/commit/a6e025e9d9511639ec106ebedc0dd312bdc9be12).
+* Ensure that `Waker::wake` works on illumos systems with poor `pipe(2)` and
+  `epoll(2)` interaction using `EPOLLET`
+  (https://github.com/tokio-rs/mio/commit/943d4249dcc17cd8b4d2250c4fa19116097248fa).
+* Fix `unix::pipe` on illumos
+  (https://github.com/tokio-rs/mio/commit/0db49f6d5caf54b12176821363d154384357e70a).
+
 # 0.7.6
 
 ## Added
@@ -182,6 +212,36 @@
 * The `fmt::Debug` implementation of `Events` is now actually useful as it
   prints all `Event`s.
 
+# 0.6.23 (Dec 01, 2020)
+
+### Changed
+- **MSRV**: Increased the MSRV from 1.18.0 (Jun 8, 2017) to 1.31.0 (Dec 6,
+  2018)
+  (https://github.com/tokio-rs/mio/commit/4879e0d32ddfd98e762fc87240e594a3ad8fca30).
+
+### Fixed
+- Work around Linux kernel < 2.6.37 bug on 32-bits making timeouts longer then
+  ~30 minutes effectively infinite
+  (https://github.com/tokio-rs/mio/commit/e7cba59950e9c9fa6194e29b5b1e72029e3df455).
+- Update miow and net2 depedencies to get rid of invalid memory layout assumption
+  (https://github.com/tokio-rs/mio/commit/13f02ac0a86d7c0c0001e5ff8960a0b4340d075c).
+
+# 0.6.22 (May 01, 2020)
+
+### Added
+- Add support for illumos target (#1294)
+
+# 0.6.21 (November 27, 2019)
+
+### Fixed
+- remove `=` dependency on `cfg-if`.
+
+# 0.6.20 (November 21, 2019)
+
+### Fixed
+- Use default IOCP concurrency value (#1161).
+- setting FD_CLOEXEC in pipe (#1095).
+
 # 0.6.19 (May 28, 2018)
 
 ### Fixed
diff --git a/Cargo.lock b/Cargo.lock
index 25ad6d6..6e36e56 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7,6 +7,12 @@
 checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
 
 [[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
 name = "env_logger"
 version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -23,9 +29,9 @@
 
 [[package]]
 name = "libc"
-version = "0.2.80"
+version = "0.2.81"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
+checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
 
 [[package]]
 name = "log"
@@ -33,12 +39,12 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
 dependencies = [
- "cfg-if",
+ "cfg-if 0.1.10",
 ]
 
 [[package]]
 name = "mio"
-version = "0.7.6"
+version = "0.7.7"
 dependencies = [
  "env_logger",
  "libc",
@@ -113,11 +119,11 @@
 
 [[package]]
 name = "socket2"
-version = "0.3.16"
+version = "0.3.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fd8b795c389288baa5f355489c65e71fd48a02104600d15c4cfbc561e9e429d"
+checksum = "2c29947abdee2a218277abeca306f25789c938e500ea5a9d4b12a5a504466902"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
  "redox_syscall",
  "winapi",
diff --git a/Cargo.toml b/Cargo.toml
index 7f0d023..1115469 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,12 +13,12 @@
 [package]
 edition = "2018"
 name = "mio"
-version = "0.7.6"
-authors = ["Carl Lerche <me@carllerche.com>"]
+version = "0.7.7"
+authors = ["Carl Lerche <me@carllerche.com>", "Thomas de Zeeuw <thomasdezeeuw@gmail.com>", "Tokio Contributors <team@tokio.rs>"]
 include = ["Cargo.toml", "LICENSE", "README.md", "CHANGELOG.md", "src/**/*.rs", "examples/**/*.rs"]
 description = "Lightweight non-blocking IO"
 homepage = "https://github.com/tokio-rs/mio"
-documentation = "https://docs.rs/mio/0.7.6"
+documentation = "https://docs.rs/mio/0.7.7"
 readme = "README.md"
 keywords = ["io", "async", "non-blocking"]
 categories = ["asynchronous"]
@@ -27,6 +27,7 @@
 [package.metadata.docs.rs]
 all-features = true
 rustdoc-args = ["--cfg", "docsrs"]
+targets = ["aarch64-apple-ios", "aarch64-linux-android", "x86_64-apple-darwin", "x86_64-pc-windows-msvc", "x86_64-sun-solaris", "x86_64-unknown-dragonfly", "x86_64-unknown-freebsd", "x86_64-unknown-linux-gnu", "x86_64-unknown-netbsd", "x86_64-unknown-openbsd"]
 
 [package.metadata.playground]
 features = ["os-poll", "os-ext", "net"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index e0937ed..e4158eb 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -6,11 +6,15 @@
 # - Update CHANGELOG.md.
 # - Update doc URL.
 # - Create git tag
-version       = "0.7.6"
+version       = "0.7.7"
 license       = "MIT"
-authors       = ["Carl Lerche <me@carllerche.com>"]
+authors       = [
+  "Carl Lerche <me@carllerche.com>",
+  "Thomas de Zeeuw <thomasdezeeuw@gmail.com>",
+  "Tokio Contributors <team@tokio.rs>",
+]
 description   = "Lightweight non-blocking IO"
-documentation = "https://docs.rs/mio/0.7.6"
+documentation = "https://docs.rs/mio/0.7.7"
 homepage      = "https://github.com/tokio-rs/mio"
 repository    = "https://github.com/tokio-rs/mio"
 readme        = "README.md"
@@ -63,6 +67,19 @@
 [package.metadata.docs.rs]
 all-features = true
 rustdoc-args = ["--cfg", "docsrs"]
+targets = [
+  "aarch64-apple-ios",
+  "aarch64-linux-android",
+  "x86_64-apple-darwin",
+  "x86_64-pc-windows-msvc",
+  "x86_64-sun-solaris",
+  "x86_64-unknown-dragonfly",
+  "x86_64-unknown-freebsd",
+  "x86_64-unknown-linux-gnu",
+  "x86_64-unknown-netbsd",
+  "x86_64-unknown-openbsd",
+]
+
 
 [package.metadata.playground]
 features = ["os-poll", "os-ext", "net"]
diff --git a/METADATA b/METADATA
index 54e4612..94c9d6c 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/mio/mio-0.7.6.crate"
+    value: "https://static.crates.io/crates/mio/mio-0.7.7.crate"
   }
-  version: "0.7.6"
+  version: "0.7.7"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2020
-    month: 11
-    day: 16
+    year: 2021
+    month: 1
+    day: 5
   }
 }
diff --git a/src/event/event.rs b/src/event/event.rs
index 959affd..9e4a95e 100644
--- a/src/event/event.rs
+++ b/src/event/event.rs
@@ -12,6 +12,7 @@
 /// [`Poll::poll`]: ../struct.Poll.html#method.poll
 /// [`Poll`]: ../struct.Poll.html
 /// [`Token`]: ../struct.Token.html
+#[derive(Clone)]
 #[repr(transparent)]
 pub struct Event {
     inner: sys::Event,
@@ -65,9 +66,9 @@
     /// Read closed readiness can be expected after any of the following have
     /// occurred:
     /// * The local stream has shutdown the read half of its socket
-    /// * The local stream has shtudown both the read half and the write half
+    /// * The local stream has shutdown both the read half and the write half
     ///   of its socket
-    /// * The peer stream has shtudown the write half its socket; this sends a
+    /// * The peer stream has shutdown the write half its socket; this sends a
     ///   `FIN` packet that has been received by the local stream
     ///
     /// Method is a best effort implementation. While some platforms may not
diff --git a/src/lib.rs b/src/lib.rs
index 1491a62..e815754 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,4 @@
-#![doc(html_root_url = "https://docs.rs/mio/0.7.6")]
+#![doc(html_root_url = "https://docs.rs/mio/0.7.7")]
 #![deny(
     missing_docs,
     missing_debug_implementations,
diff --git a/src/net/tcp/socket.rs b/src/net/tcp/socket.rs
index 35a589c..69fbacf 100644
--- a/src/net/tcp/socket.rs
+++ b/src/net/tcp/socket.rs
@@ -218,7 +218,8 @@
     ///   be passed every time it is called.
     ///
     /// # Examples
-    /// ```
+    #[cfg_attr(feature = "os-poll", doc = "```")]
+    #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
     /// use mio::net::{TcpSocket, TcpKeepalive};
     /// use std::time::Duration;
     ///
diff --git a/src/net/udp.rs b/src/net/udp.rs
index 436b4cc..c5c3ba9 100644
--- a/src/net/udp.rs
+++ b/src/net/udp.rs
@@ -511,6 +511,12 @@
         self.inner.leave_multicast_v6(multiaddr, interface)
     }
 
+    /// Get the value of the `IPV6_V6ONLY` option on this socket.
+    #[allow(clippy::trivially_copy_pass_by_ref)]
+    pub fn only_v6(&self) -> io::Result<bool> {
+        sys::udp::only_v6(&self.inner)
+    }
+
     /// Get the value of the `SO_ERROR` option on this socket.
     ///
     /// This will retrieve the stored error in the underlying socket, clearing
diff --git a/src/poll.rs b/src/poll.rs
index b06f138..a6f4ab0 100644
--- a/src/poll.rs
+++ b/src/poll.rs
@@ -361,7 +361,7 @@
 #[cfg(unix)]
 impl AsRawFd for Poll {
     fn as_raw_fd(&self) -> RawFd {
-        self.registry.selector.as_raw_fd()
+        self.registry.as_raw_fd()
     }
 }
 
@@ -528,7 +528,7 @@
     /// // the token is the same it must be specified.
     /// poll.registry().reregister(
     ///     &mut socket,
-    ///     Token(2),
+    ///     Token(0),
     ///     Interest::WRITABLE)?;
     /// #     Ok(())
     /// # }
@@ -636,6 +636,13 @@
     }
 }
 
+#[cfg(unix)]
+impl AsRawFd for Registry {
+    fn as_raw_fd(&self) -> RawFd {
+        self.selector.as_raw_fd()
+    }
+}
+
 /// Get access to the `sys::Selector` from `Registry`.
 pub(crate) fn selector(registry: &Registry) -> &sys::Selector {
     &registry.selector
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 @@
     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 @@
 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 @@
         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 @@
         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 {
+    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 {
+    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 @@
     }
 }
 
+#[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 @@
         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 @@
             .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 @@
 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 @@
         }
 
         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 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 @@
         .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)
+}