diff --git a/Cargo.toml b/Cargo.toml index 0db56f0..bd181e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,3 +20,6 @@ exclude = ["/.*"] async-io = "1.6.0" blocking = "1.0.0" futures-lite = "1.11.0" + +[build-dependencies] +autocfg = "1" \ No newline at end of file diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..db1e913 --- /dev/null +++ b/build.rs @@ -0,0 +1,16 @@ +fn main() { + let cfg = match autocfg::AutoCfg::new() { + Ok(cfg) => cfg, + Err(e) => { + println!( + "cargo-warning=async-net: failed to detect compiler features: {}", + e + ); + return; + } + }; + + if !cfg.probe_rustc_version(1, 63) { + autocfg::emit("async_net_no_io_safety"); + } +} diff --git a/src/tcp.rs b/src/tcp.rs index 56edf70..2c1d10d 100644 --- a/src/tcp.rs +++ b/src/tcp.rs @@ -2,10 +2,14 @@ use std::convert::TryFrom; use std::fmt; use std::io::{self, IoSlice, Read as _, Write as _}; use std::net::{Shutdown, SocketAddr}; +#[cfg(all(not(async_net_no_io_safety), unix))] +use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd}; #[cfg(unix)] use std::os::unix::io::{AsRawFd, RawFd}; #[cfg(windows)] use std::os::windows::io::{AsRawSocket, RawSocket}; +#[cfg(all(not(async_net_no_io_safety), windows))] +use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket}; use std::panic::{RefUnwindSafe, UnwindSafe}; use std::pin::Pin; use std::sync::Arc; @@ -240,6 +244,22 @@ impl AsRawFd for TcpListener { } } +#[cfg(all(not(async_net_no_io_safety), unix))] +impl AsFd for TcpListener { + fn as_fd(&self) -> BorrowedFd<'_> { + self.inner.get_ref().as_fd() + } +} + +#[cfg(all(not(async_net_no_io_safety), unix))] +impl TryFrom for TcpListener { + type Error = io::Error; + + fn try_from(value: OwnedFd) -> Result { + Self::try_from(std::net::TcpListener::from(value)) + } +} + #[cfg(windows)] impl AsRawSocket for TcpListener { fn as_raw_socket(&self) -> RawSocket { @@ -247,6 +267,22 @@ impl AsRawSocket for TcpListener { } } +#[cfg(all(not(async_net_no_io_safety), windows))] +impl AsSocket for TcpListener { + fn as_socket(&self) -> BorrowedSocket<'_> { + self.inner.get_ref().as_socket() + } +} + +#[cfg(all(not(async_net_no_io_safety), windows))] +impl TryFrom for TcpListener { + type Error = io::Error; + + fn try_from(value: OwnedSocket) -> Result { + Self::try_from(std::net::TcpListener::from(value)) + } +} + /// A stream of incoming TCP connections. /// /// This stream is infinite, i.e awaiting the next connection will never result in [`None`]. It is @@ -574,6 +610,22 @@ impl AsRawFd for TcpStream { } } +#[cfg(all(not(async_net_no_io_safety), unix))] +impl AsFd for TcpStream { + fn as_fd(&self) -> BorrowedFd<'_> { + self.inner.get_ref().as_fd() + } +} + +#[cfg(all(not(async_net_no_io_safety), unix))] +impl TryFrom for TcpStream { + type Error = io::Error; + + fn try_from(value: OwnedFd) -> Result { + Self::try_from(std::net::TcpStream::from(value)) + } +} + #[cfg(windows)] impl AsRawSocket for TcpStream { fn as_raw_socket(&self) -> RawSocket { @@ -581,6 +633,22 @@ impl AsRawSocket for TcpStream { } } +#[cfg(all(not(async_net_no_io_safety), windows))] +impl AsSocket for TcpStream { + fn as_socket(&self) -> BorrowedSocket<'_> { + self.inner.get_ref().as_socket() + } +} + +#[cfg(all(not(async_net_no_io_safety), windows))] +impl TryFrom for TcpStream { + type Error = io::Error; + + fn try_from(value: OwnedSocket) -> Result { + Self::try_from(std::net::TcpStream::from(value)) + } +} + impl AsyncRead for TcpStream { fn poll_read( mut self: Pin<&mut Self>, diff --git a/src/udp.rs b/src/udp.rs index c85f9f6..af14c47 100644 --- a/src/udp.rs +++ b/src/udp.rs @@ -1,10 +1,14 @@ use std::convert::TryFrom; use std::io; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; +#[cfg(all(not(async_net_no_io_safety), unix))] +use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd}; #[cfg(unix)] use std::os::unix::io::{AsRawFd, RawFd}; #[cfg(windows)] use std::os::windows::io::{AsRawSocket, RawSocket}; +#[cfg(all(not(async_net_no_io_safety), windows))] +use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket}; use std::sync::Arc; use async_io::Async; @@ -623,9 +627,41 @@ impl AsRawFd for UdpSocket { } } +#[cfg(all(not(async_net_no_io_safety), unix))] +impl AsFd for UdpSocket { + fn as_fd(&self) -> BorrowedFd<'_> { + self.inner.get_ref().as_fd() + } +} + +#[cfg(all(not(async_net_no_io_safety), unix))] +impl TryFrom for UdpSocket { + type Error = io::Error; + + fn try_from(value: OwnedFd) -> Result { + Self::try_from(std::net::UdpSocket::from(value)) + } +} + #[cfg(windows)] impl AsRawSocket for UdpSocket { fn as_raw_socket(&self) -> RawSocket { self.inner.as_raw_socket() } } + +#[cfg(all(not(async_net_no_io_safety), windows))] +impl AsSocket for UdpSocket { + fn as_socket(&self) -> BorrowedSocket<'_> { + self.inner.get_ref().as_socket() + } +} + +#[cfg(all(not(async_net_no_io_safety), windows))] +impl TryFrom for UdpSocket { + type Error = io::Error; + + fn try_from(value: OwnedSocket) -> Result { + Self::try_from(std::net::UdpSocket::from(value)) + } +} diff --git a/src/unix.rs b/src/unix.rs index 967c76e..3d2c7ba 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -6,6 +6,8 @@ use std::convert::TryFrom; use std::fmt; use std::io::{self, Read as _, Write as _}; use std::net::Shutdown; +#[cfg(not(async_net_no_io_safety))] +use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd}; #[cfg(unix)] use std::os::unix::io::{AsRawFd, RawFd}; #[cfg(windows)] @@ -172,6 +174,22 @@ impl AsRawFd for UnixListener { } } +#[cfg(all(not(async_net_no_io_safety), unix))] +impl AsFd for UnixListener { + fn as_fd(&self) -> BorrowedFd<'_> { + self.inner.get_ref().as_fd() + } +} + +#[cfg(all(not(async_net_no_io_safety), unix))] +impl TryFrom for UnixListener { + type Error = io::Error; + + fn try_from(value: OwnedFd) -> Result { + Self::try_from(std::os::unix::net::UnixListener::from(value)) + } +} + #[cfg(windows)] impl AsRawSocket for UnixListener { fn as_raw_socket(&self) -> RawSocket { @@ -371,6 +389,22 @@ impl AsRawFd for UnixStream { } } +#[cfg(all(not(async_net_no_io_safety), unix))] +impl AsFd for UnixStream { + fn as_fd(&self) -> BorrowedFd<'_> { + self.inner.get_ref().as_fd() + } +} + +#[cfg(all(not(async_net_no_io_safety), unix))] +impl TryFrom for UnixStream { + type Error = io::Error; + + fn try_from(value: OwnedFd) -> Result { + Self::try_from(std::os::unix::net::UnixStream::from(value)) + } +} + #[cfg(windows)] impl AsRawSocket for UnixStream { fn as_raw_socket(&self) -> RawSocket {