From 5797e08968ac0e23ffb502573f665d0a7fd37115 Mon Sep 17 00:00:00 2001 From: jtnunley Date: Thu, 11 Aug 2022 13:17:55 -0700 Subject: [PATCH 1/4] add io-safe traits --- Cargo.toml | 3 +++ src/tcp.rs | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/udp.rs | 36 ++++++++++++++++++++++++++++ src/unix.rs | 34 +++++++++++++++++++++++++++ 4 files changed, 141 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 0db56f0..8e71296 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" + +[features] +io_safety = [] \ No newline at end of file diff --git a/src/tcp.rs b/src/tcp.rs index 56edf70..023910b 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(feature = "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(feature = "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(feature = "io_safety", unix))] +impl AsFd for TcpListener { + fn as_fd(&self) -> BorrowedFd<'_> { + self.inner.get_ref().as_fd() + } +} + +#[cfg(all(feature = "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(feature = "io_safety", windows))] +impl AsSocket for TcpListener { + fn as_socket(&self) -> BorrowedSocket<'_> { + self.inner.get_ref().as_socket() + } +} + +#[cfg(all(feature = "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(feature = "io_safety", unix))] +impl AsFd for TcpStream { + fn as_fd(&self) -> BorrowedFd<'_> { + self.inner.get_ref().as_fd() + } +} + +#[cfg(all(feature = "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(feature = "io_safety", windows))] +impl AsSocket for TcpStream { + fn as_socket(&self) -> BorrowedSocket<'_> { + self.inner.get_ref().as_socket() + } +} + +#[cfg(all(feature = "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..93ddbec 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(feature = "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(feature = "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(feature = "io_safety", unix))] +impl AsFd for UdpSocket { + fn as_fd(&self) -> BorrowedFd<'_> { + self.inner.get_ref().as_fd() + } +} + +#[cfg(all(feature = "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(feature = "io_safety", windows))] +impl AsSocket for UdpSocket { + fn as_socket(&self) -> BorrowedSocket<'_> { + self.inner.get_ref().as_socket() + } +} + +#[cfg(all(feature = "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..a8c8b2c 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(feature = "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(feature = "io_safety", unix))] +impl AsFd for UnixListener { + fn as_fd(&self) -> BorrowedFd<'_> { + self.inner.get_ref().as_fd() + } +} + +#[cfg(all(feature = "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(feature = "io_safety", unix))] +impl AsFd for UnixStream { + fn as_fd(&self) -> BorrowedFd<'_> { + self.inner.get_ref().as_fd() + } +} + +#[cfg(all(feature = "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 { From 6c5c8bd653ea22c9629d955e48e7279b91e74a39 Mon Sep 17 00:00:00 2001 From: jtnunley Date: Sat, 13 Aug 2022 17:40:27 -0700 Subject: [PATCH 2/4] use autocfg --- Cargo.toml | 4 ++-- build.rs | 18 ++++++++++++++++++ src/tcp.rs | 20 ++++++++++---------- src/udp.rs | 12 ++++++------ src/unix.rs | 10 +++++----- 5 files changed, 41 insertions(+), 23 deletions(-) create mode 100644 build.rs diff --git a/Cargo.toml b/Cargo.toml index 8e71296..bd181e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,5 +21,5 @@ async-io = "1.6.0" blocking = "1.0.0" futures-lite = "1.11.0" -[features] -io_safety = [] \ No newline at end of file +[build-dependencies] +autocfg = "1" \ No newline at end of file diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..0d95e13 --- /dev/null +++ b/build.rs @@ -0,0 +1,18 @@ +const TEST_EXPR: &str = "{ +#[cfg(unix)] +fn _test(_: I) {} +#[cfg(unix)] +fn _test2(_: std::os::unix::io::OwnedFd) {} +#[cfg(windows)] +fn _test(_: I) {} +#[cfg(windows)] +fn _test2(_: std::os::windows::io::OwnedSocket) {} +}"; + +fn main() { + let cfg = autocfg::new(); + + if cfg.probe_expression(TEST_EXPR) { + autocfg::emit("has_io_safety"); + } +} \ No newline at end of file diff --git a/src/tcp.rs b/src/tcp.rs index 023910b..00d971d 100644 --- a/src/tcp.rs +++ b/src/tcp.rs @@ -2,13 +2,13 @@ use std::convert::TryFrom; use std::fmt; use std::io::{self, IoSlice, Read as _, Write as _}; use std::net::{Shutdown, SocketAddr}; -#[cfg(all(feature = "io_safety", unix))] +#[cfg(all(has_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(feature = "io_safety", windows))] +#[cfg(all(has_io_safety, windows))] use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket}; use std::panic::{RefUnwindSafe, UnwindSafe}; use std::pin::Pin; @@ -244,14 +244,14 @@ impl AsRawFd for TcpListener { } } -#[cfg(all(feature = "io_safety", unix))] +#[cfg(all(has_io_safety, unix))] impl AsFd for TcpListener { fn as_fd(&self) -> BorrowedFd<'_> { self.inner.get_ref().as_fd() } } -#[cfg(all(feature = "io_safety", unix))] +#[cfg(all(has_io_safety, unix))] impl TryFrom for TcpListener { type Error = io::Error; @@ -267,14 +267,14 @@ impl AsRawSocket for TcpListener { } } -#[cfg(all(feature = "io_safety", windows))] +#[cfg(all(has_io_safety, windows))] impl AsSocket for TcpListener { fn as_socket(&self) -> BorrowedSocket<'_> { self.inner.get_ref().as_socket() } } -#[cfg(all(feature = "io_safety", windows))] +#[cfg(all(has_io_safety, windows))] impl TryFrom for TcpListener { type Error = io::Error; @@ -610,14 +610,14 @@ impl AsRawFd for TcpStream { } } -#[cfg(all(feature = "io_safety", unix))] +#[cfg(all(has_io_safety, unix))] impl AsFd for TcpStream { fn as_fd(&self) -> BorrowedFd<'_> { self.inner.get_ref().as_fd() } } -#[cfg(all(feature = "io_safety", unix))] +#[cfg(all(has_io_safety, unix))] impl TryFrom for TcpStream { type Error = io::Error; @@ -633,14 +633,14 @@ impl AsRawSocket for TcpStream { } } -#[cfg(all(feature = "io_safety", windows))] +#[cfg(all(has_io_safety, windows))] impl AsSocket for TcpStream { fn as_socket(&self) -> BorrowedSocket<'_> { self.inner.get_ref().as_socket() } } -#[cfg(all(feature = "io_safety", windows))] +#[cfg(all(has_io_safety, windows))] impl TryFrom for TcpStream { type Error = io::Error; diff --git a/src/udp.rs b/src/udp.rs index 93ddbec..e3ee717 100644 --- a/src/udp.rs +++ b/src/udp.rs @@ -1,13 +1,13 @@ use std::convert::TryFrom; use std::io; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; -#[cfg(all(feature = "io_safety", unix))] +#[cfg(all(has_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(feature = "io_safety", windows))] +#[cfg(all(has_io_safety, windows))] use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket}; use std::sync::Arc; @@ -627,14 +627,14 @@ impl AsRawFd for UdpSocket { } } -#[cfg(all(feature = "io_safety", unix))] +#[cfg(all(has_io_safety, unix))] impl AsFd for UdpSocket { fn as_fd(&self) -> BorrowedFd<'_> { self.inner.get_ref().as_fd() } } -#[cfg(all(feature = "io_safety", unix))] +#[cfg(all(has_io_safety, unix))] impl TryFrom for UdpSocket { type Error = io::Error; @@ -650,14 +650,14 @@ impl AsRawSocket for UdpSocket { } } -#[cfg(all(feature = "io_safety", windows))] +#[cfg(all(has_io_safety, windows))] impl AsSocket for UdpSocket { fn as_socket(&self) -> BorrowedSocket<'_> { self.inner.get_ref().as_socket() } } -#[cfg(all(feature = "io_safety", windows))] +#[cfg(all(has_io_safety, windows))] impl TryFrom for UdpSocket { type Error = io::Error; diff --git a/src/unix.rs b/src/unix.rs index a8c8b2c..07c9ff7 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -6,7 +6,7 @@ use std::convert::TryFrom; use std::fmt; use std::io::{self, Read as _, Write as _}; use std::net::Shutdown; -#[cfg(feature = "io_safety")] +#[cfg(has_io_safety)] use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd}; #[cfg(unix)] use std::os::unix::io::{AsRawFd, RawFd}; @@ -174,14 +174,14 @@ impl AsRawFd for UnixListener { } } -#[cfg(all(feature = "io_safety", unix))] +#[cfg(all(has_io_safety, unix))] impl AsFd for UnixListener { fn as_fd(&self) -> BorrowedFd<'_> { self.inner.get_ref().as_fd() } } -#[cfg(all(feature = "io_safety", unix))] +#[cfg(all(has_io_safety, unix))] impl TryFrom for UnixListener { type Error = io::Error; @@ -389,14 +389,14 @@ impl AsRawFd for UnixStream { } } -#[cfg(all(feature = "io_safety", unix))] +#[cfg(all(has_io_safety, unix))] impl AsFd for UnixStream { fn as_fd(&self) -> BorrowedFd<'_> { self.inner.get_ref().as_fd() } } -#[cfg(all(feature = "io_safety", unix))] +#[cfg(all(has_io_safety, unix))] impl TryFrom for UnixStream { type Error = io::Error; From 7c9f5004234b28cd4ac673b0e49b76fbe59cba2a Mon Sep 17 00:00:00 2001 From: jtnunley Date: Mon, 15 Aug 2022 06:27:10 -0700 Subject: [PATCH 3/4] fmt --- build.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.rs b/build.rs index 0d95e13..14664a3 100644 --- a/build.rs +++ b/build.rs @@ -11,8 +11,8 @@ fn _test2(_: std::os::windows::io::OwnedSocket) {} fn main() { let cfg = autocfg::new(); - + if cfg.probe_expression(TEST_EXPR) { autocfg::emit("has_io_safety"); } -} \ No newline at end of file +} From 845865948a476a8b7944e4e7ced3eb4c2ca63eac Mon Sep 17 00:00:00 2001 From: jtnunley Date: Wed, 17 Aug 2022 11:49:22 -0700 Subject: [PATCH 4/4] autocfg fixes --- build.rs | 26 ++++++++++++-------------- src/tcp.rs | 20 ++++++++++---------- src/udp.rs | 12 ++++++------ src/unix.rs | 10 +++++----- 4 files changed, 33 insertions(+), 35 deletions(-) diff --git a/build.rs b/build.rs index 14664a3..db1e913 100644 --- a/build.rs +++ b/build.rs @@ -1,18 +1,16 @@ -const TEST_EXPR: &str = "{ -#[cfg(unix)] -fn _test(_: I) {} -#[cfg(unix)] -fn _test2(_: std::os::unix::io::OwnedFd) {} -#[cfg(windows)] -fn _test(_: I) {} -#[cfg(windows)] -fn _test2(_: std::os::windows::io::OwnedSocket) {} -}"; - fn main() { - let cfg = autocfg::new(); + 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_expression(TEST_EXPR) { - autocfg::emit("has_io_safety"); + 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 00d971d..2c1d10d 100644 --- a/src/tcp.rs +++ b/src/tcp.rs @@ -2,13 +2,13 @@ use std::convert::TryFrom; use std::fmt; use std::io::{self, IoSlice, Read as _, Write as _}; use std::net::{Shutdown, SocketAddr}; -#[cfg(all(has_io_safety, unix))] +#[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(has_io_safety, windows))] +#[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; @@ -244,14 +244,14 @@ impl AsRawFd for TcpListener { } } -#[cfg(all(has_io_safety, unix))] +#[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(has_io_safety, unix))] +#[cfg(all(not(async_net_no_io_safety), unix))] impl TryFrom for TcpListener { type Error = io::Error; @@ -267,14 +267,14 @@ impl AsRawSocket for TcpListener { } } -#[cfg(all(has_io_safety, windows))] +#[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(has_io_safety, windows))] +#[cfg(all(not(async_net_no_io_safety), windows))] impl TryFrom for TcpListener { type Error = io::Error; @@ -610,14 +610,14 @@ impl AsRawFd for TcpStream { } } -#[cfg(all(has_io_safety, unix))] +#[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(has_io_safety, unix))] +#[cfg(all(not(async_net_no_io_safety), unix))] impl TryFrom for TcpStream { type Error = io::Error; @@ -633,14 +633,14 @@ impl AsRawSocket for TcpStream { } } -#[cfg(all(has_io_safety, windows))] +#[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(has_io_safety, windows))] +#[cfg(all(not(async_net_no_io_safety), windows))] impl TryFrom for TcpStream { type Error = io::Error; diff --git a/src/udp.rs b/src/udp.rs index e3ee717..af14c47 100644 --- a/src/udp.rs +++ b/src/udp.rs @@ -1,13 +1,13 @@ use std::convert::TryFrom; use std::io; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; -#[cfg(all(has_io_safety, unix))] +#[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(has_io_safety, windows))] +#[cfg(all(not(async_net_no_io_safety), windows))] use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket}; use std::sync::Arc; @@ -627,14 +627,14 @@ impl AsRawFd for UdpSocket { } } -#[cfg(all(has_io_safety, unix))] +#[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(has_io_safety, unix))] +#[cfg(all(not(async_net_no_io_safety), unix))] impl TryFrom for UdpSocket { type Error = io::Error; @@ -650,14 +650,14 @@ impl AsRawSocket for UdpSocket { } } -#[cfg(all(has_io_safety, windows))] +#[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(has_io_safety, windows))] +#[cfg(all(not(async_net_no_io_safety), windows))] impl TryFrom for UdpSocket { type Error = io::Error; diff --git a/src/unix.rs b/src/unix.rs index 07c9ff7..3d2c7ba 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -6,7 +6,7 @@ use std::convert::TryFrom; use std::fmt; use std::io::{self, Read as _, Write as _}; use std::net::Shutdown; -#[cfg(has_io_safety)] +#[cfg(not(async_net_no_io_safety))] use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd}; #[cfg(unix)] use std::os::unix::io::{AsRawFd, RawFd}; @@ -174,14 +174,14 @@ impl AsRawFd for UnixListener { } } -#[cfg(all(has_io_safety, unix))] +#[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(has_io_safety, unix))] +#[cfg(all(not(async_net_no_io_safety), unix))] impl TryFrom for UnixListener { type Error = io::Error; @@ -389,14 +389,14 @@ impl AsRawFd for UnixStream { } } -#[cfg(all(has_io_safety, unix))] +#[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(has_io_safety, unix))] +#[cfg(all(not(async_net_no_io_safety), unix))] impl TryFrom for UnixStream { type Error = io::Error;