diff --git a/src/net/tcp/listener.rs b/src/net/tcp/listener.rs index 1142b3612..2e27a7641 100644 --- a/src/net/tcp/listener.rs +++ b/src/net/tcp/listener.rs @@ -1,12 +1,14 @@ use std::net::{self, SocketAddr}; #[cfg(any(unix, target_os = "wasi"))] -use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; +use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; // TODO: once is fixed this // can use `std::os::fd` and be merged with the above. #[cfg(target_os = "hermit")] -use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; +use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; #[cfg(windows)] -use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket}; +use std::os::windows::io::{ + AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket, +}; use std::{fmt, io}; use crate::io_source::IoSource; @@ -195,6 +197,13 @@ impl FromRawFd for TcpListener { } } +#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))] +impl From for OwnedFd { + fn from(tcp_listener: TcpListener) -> Self { + tcp_listener.inner.into_inner().into() + } +} + #[cfg(any(unix, target_os = "hermit", target_os = "wasi"))] impl AsFd for TcpListener { fn as_fd(&self) -> BorrowedFd<'_> { @@ -202,6 +211,19 @@ impl AsFd for TcpListener { } } +#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))] +impl From for TcpListener { + /// Converts a `RawFd` to a `TcpListener`. + /// + /// # Notes + /// + /// The caller is responsible for ensuring that the socket is in + /// non-blocking mode. + fn from(fd: OwnedFd) -> Self { + TcpListener::from_std(From::from(fd)) + } +} + #[cfg(windows)] impl IntoRawSocket for TcpListener { fn into_raw_socket(self) -> RawSocket { @@ -229,6 +251,33 @@ impl FromRawSocket for TcpListener { } } +#[cfg(windows)] +impl From for OwnedSocket { + fn from(tcp_listener: TcpListener) -> Self { + tcp_listener.inner.into_inner().into() + } +} + +#[cfg(windows)] +impl AsSocket for TcpListener { + fn as_socket(&self) -> BorrowedSocket<'_> { + self.inner.as_socket() + } +} + +#[cfg(windows)] +impl From for TcpListener { + /// Converts a `RawSocket` to a `TcpListener`. + /// + /// # Notes + /// + /// The caller is responsible for ensuring that the socket is in + /// non-blocking mode. + fn from(socket: OwnedSocket) -> Self { + TcpListener::from_std(From::from(socket)) + } +} + impl From for net::TcpListener { fn from(listener: TcpListener) -> Self { // Safety: This is safe since we are extracting the raw fd from a well-constructed diff --git a/src/net/tcp/stream.rs b/src/net/tcp/stream.rs index 377c8e914..f3db74fab 100644 --- a/src/net/tcp/stream.rs +++ b/src/net/tcp/stream.rs @@ -2,13 +2,15 @@ use std::fmt; use std::io::{self, IoSlice, IoSliceMut, Read, Write}; use std::net::{self, Shutdown, SocketAddr}; #[cfg(any(unix, target_os = "wasi"))] -use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; +use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; // TODO: once is fixed this // can use `std::os::fd` and be merged with the above. #[cfg(target_os = "hermit")] -use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; +use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; #[cfg(windows)] -use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket}; +use std::os::windows::io::{ + AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket, +}; use crate::io_source::IoSource; #[cfg(not(target_os = "wasi"))] @@ -377,6 +379,13 @@ impl FromRawFd for TcpStream { } } +#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))] +impl From for OwnedFd { + fn from(tcp_stream: TcpStream) -> Self { + tcp_stream.inner.into_inner().into() + } +} + #[cfg(any(unix, target_os = "hermit", target_os = "wasi"))] impl AsFd for TcpStream { fn as_fd(&self) -> BorrowedFd<'_> { @@ -384,6 +393,19 @@ impl AsFd for TcpStream { } } +#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))] +impl From for TcpStream { + /// Converts a `RawFd` to a `TcpStream`. + /// + /// # Notes + /// + /// The caller is responsible for ensuring that the socket is in + /// non-blocking mode. + fn from(fd: OwnedFd) -> Self { + TcpStream::from_std(From::from(fd)) + } +} + #[cfg(windows)] impl IntoRawSocket for TcpStream { fn into_raw_socket(self) -> RawSocket { @@ -411,6 +433,33 @@ impl FromRawSocket for TcpStream { } } +#[cfg(windows)] +impl From for OwnedSocket { + fn from(tcp_stream: TcpStream) -> Self { + tcp_stream.inner.into_inner().into() + } +} + +#[cfg(windows)] +impl AsSocket for TcpStream { + fn as_socket(&self) -> BorrowedSocket<'_> { + self.inner.as_socket() + } +} + +#[cfg(windows)] +impl From for TcpStream { + /// Converts a `RawSocket` to a `TcpStream`. + /// + /// # Notes + /// + /// The caller is responsible for ensuring that the socket is in + /// non-blocking mode. + fn from(socket: OwnedSocket) -> Self { + TcpStream::from_std(From::from(socket)) + } +} + impl From for net::TcpStream { fn from(stream: TcpStream) -> Self { // Safety: This is safe since we are extracting the raw fd from a well-constructed diff --git a/src/net/udp.rs b/src/net/udp.rs index b743f8f7c..e5013ba5b 100644 --- a/src/net/udp.rs +++ b/src/net/udp.rs @@ -9,13 +9,15 @@ use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; #[cfg(any(unix, target_os = "wasi"))] -use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; +use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; // TODO: once is fixed this // can use `std::os::fd` and be merged with the above. #[cfg(target_os = "hermit")] -use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; +use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; #[cfg(windows)] -use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket}; +use std::os::windows::io::{ + AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket, +}; use std::{fmt, io, net}; use crate::io_source::IoSource; @@ -671,6 +673,13 @@ impl FromRawFd for UdpSocket { } } +#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))] +impl From for OwnedFd { + fn from(udp_socket: UdpSocket) -> Self { + udp_socket.inner.into_inner().into() + } +} + #[cfg(any(unix, target_os = "hermit", target_os = "wasi"))] impl AsFd for UdpSocket { fn as_fd(&self) -> BorrowedFd<'_> { @@ -678,6 +687,19 @@ impl AsFd for UdpSocket { } } +#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))] +impl From for UdpSocket { + /// Converts a `RawFd` to a `UdpSocket`. + /// + /// # Notes + /// + /// The caller is responsible for ensuring that the socket is in + /// non-blocking mode. + fn from(fd: OwnedFd) -> Self { + UdpSocket::from_std(From::from(fd)) + } +} + #[cfg(windows)] impl IntoRawSocket for UdpSocket { fn into_raw_socket(self) -> RawSocket { @@ -705,6 +727,33 @@ impl FromRawSocket for UdpSocket { } } +#[cfg(windows)] +impl From for OwnedSocket { + fn from(udp_socket: UdpSocket) -> Self { + udp_socket.inner.into_inner().into() + } +} + +#[cfg(windows)] +impl AsSocket for UdpSocket { + fn as_socket(&self) -> BorrowedSocket<'_> { + self.inner.as_socket() + } +} + +#[cfg(windows)] +impl From for UdpSocket { + /// Converts a `RawSocket` to a `UdpSocket`. + /// + /// # Notes + /// + /// The caller is responsible for ensuring that the socket is in + /// non-blocking mode. + fn from(socket: OwnedSocket) -> Self { + UdpSocket::from_std(From::from(socket)) + } +} + impl From for net::UdpSocket { fn from(socket: UdpSocket) -> Self { // Safety: This is safe since we are extracting the raw fd from a well-constructed diff --git a/src/net/uds/datagram.rs b/src/net/uds/datagram.rs index bab460598..73fea0731 100644 --- a/src/net/uds/datagram.rs +++ b/src/net/uds/datagram.rs @@ -1,5 +1,5 @@ use std::net::Shutdown; -use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; +use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use std::os::unix::net::{self, SocketAddr}; use std::path::Path; use std::{fmt, io}; @@ -249,8 +249,20 @@ impl From for net::UnixDatagram { } } +impl From for OwnedFd { + fn from(unix_datagram: UnixDatagram) -> Self { + unix_datagram.inner.into_inner().into() + } +} + impl AsFd for UnixDatagram { fn as_fd(&self) -> BorrowedFd<'_> { self.inner.as_fd() } } + +impl From for UnixDatagram { + fn from(fd: OwnedFd) -> Self { + UnixDatagram::from_std(From::from(fd)) + } +} diff --git a/src/net/uds/listener.rs b/src/net/uds/listener.rs index bac82e826..a255972a5 100644 --- a/src/net/uds/listener.rs +++ b/src/net/uds/listener.rs @@ -1,4 +1,4 @@ -use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; +use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use std::os::unix::net::{self, SocketAddr}; use std::path::Path; use std::{fmt, io}; @@ -118,8 +118,20 @@ impl From for net::UnixListener { } } +impl From for OwnedFd { + fn from(unix_listener: UnixListener) -> Self { + unix_listener.inner.into_inner().into() + } +} + impl AsFd for UnixListener { fn as_fd(&self) -> BorrowedFd<'_> { self.inner.as_fd() } } + +impl From for UnixListener { + fn from(fd: OwnedFd) -> Self { + UnixListener::from_std(From::from(fd)) + } +} diff --git a/src/net/uds/stream.rs b/src/net/uds/stream.rs index a25a41998..1e23afbc1 100644 --- a/src/net/uds/stream.rs +++ b/src/net/uds/stream.rs @@ -1,7 +1,7 @@ use std::fmt; use std::io::{self, IoSlice, IoSliceMut, Read, Write}; use std::net::Shutdown; -use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; +use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use std::os::unix::net::{self, SocketAddr}; use std::path::Path; @@ -262,8 +262,20 @@ impl From for net::UnixStream { } } +impl From for OwnedFd { + fn from(unix_stream: UnixStream) -> Self { + unix_stream.inner.into_inner().into() + } +} + impl AsFd for UnixStream { fn as_fd(&self) -> BorrowedFd<'_> { self.inner.as_fd() } } + +impl From for UnixStream { + fn from(fd: OwnedFd) -> Self { + UnixStream::from_std(From::from(fd)) + } +} diff --git a/src/sys/unix/pipe.rs b/src/sys/unix/pipe.rs index 3fc4f1575..8e8675375 100644 --- a/src/sys/unix/pipe.rs +++ b/src/sys/unix/pipe.rs @@ -65,7 +65,7 @@ pub(crate) fn new_raw() -> io::Result<[RawFd; 2]> { cfg_os_ext! { use std::fs::File; use std::io::{IoSlice, IoSliceMut, Read, Write}; -use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd}; +use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd}; use std::process::{ChildStderr, ChildStdin, ChildStdout}; use crate::io_source::IoSource; @@ -378,12 +378,26 @@ impl IntoRawFd for Sender { } } +impl From for OwnedFd { + fn from(sender: Sender) -> Self { + sender.inner.into_inner().into() + } +} + impl AsFd for Sender { fn as_fd(&self) -> BorrowedFd<'_> { self.inner.as_fd() } } +impl From for Sender { + fn from(fd: OwnedFd) -> Self { + Sender { + inner: IoSource::new(File::from(fd)), + } + } +} + /// Receiving end of an Unix pipe. /// /// See [`new`] for documentation, including examples. @@ -551,12 +565,26 @@ impl FromRawFd for Receiver { } } +impl From for OwnedFd { + fn from(receiver: Receiver) -> Self { + receiver.inner.into_inner().into() + } +} + impl AsFd for Receiver { fn as_fd(&self) -> BorrowedFd<'_> { self.inner.as_fd() } } +impl From for Receiver { + fn from(fd: OwnedFd) -> Self { + Receiver { + inner: IoSource::new(File::from(fd)), + } + } +} + #[cfg(not(any(target_os = "illumos", target_os = "solaris", target_os = "vita")))] fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> { let value = nonblocking as libc::c_int;