Skip to content

Commit

Permalink
Implement more I/O safety traits
Browse files Browse the repository at this point in the history
Implement `From<OwnedFd>` and `Into<OwnedFd>` for types that implement
`FromRawFd` and `IntoRawFd`.

And on Windows, implement `From<OwnedSocket>`, `Into<OwnedSocket>`, and
`AsSocket` for types that implement `FromRawSocket`, `IntoRawSocket`,
and `AsRawSocket`.
  • Loading branch information
sunfishcode authored Sep 28, 2024
1 parent 8b6c4b5 commit d8d68ac
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 13 deletions.
55 changes: 52 additions & 3 deletions src/net/tcp/listener.rs
Original file line number Diff line number Diff line change
@@ -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 <https://github.com/rust-lang/rust/issues/126198> 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;
Expand Down Expand Up @@ -195,13 +197,33 @@ impl FromRawFd for TcpListener {
}
}

#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
impl From<TcpListener> 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<'_> {
self.inner.as_fd()
}
}

#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
impl From<OwnedFd> 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 {
Expand Down Expand Up @@ -229,6 +251,33 @@ impl FromRawSocket for TcpListener {
}
}

#[cfg(windows)]
impl From<TcpListener> 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<OwnedSocket> 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<TcpListener> for net::TcpListener {
fn from(listener: TcpListener) -> Self {
// Safety: This is safe since we are extracting the raw fd from a well-constructed
Expand Down
55 changes: 52 additions & 3 deletions src/net/tcp/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://github.com/rust-lang/rust/issues/126198> 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"))]
Expand Down Expand Up @@ -377,13 +379,33 @@ impl FromRawFd for TcpStream {
}
}

#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
impl From<TcpStream> 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<'_> {
self.inner.as_fd()
}
}

#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
impl From<OwnedFd> 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 {
Expand Down Expand Up @@ -411,6 +433,33 @@ impl FromRawSocket for TcpStream {
}
}

#[cfg(windows)]
impl From<TcpStream> 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<OwnedSocket> 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<TcpStream> for net::TcpStream {
fn from(stream: TcpStream) -> Self {
// Safety: This is safe since we are extracting the raw fd from a well-constructed
Expand Down
55 changes: 52 additions & 3 deletions src/net/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://github.com/rust-lang/rust/issues/126198> 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;
Expand Down Expand Up @@ -671,13 +673,33 @@ impl FromRawFd for UdpSocket {
}
}

#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
impl From<UdpSocket> 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<'_> {
self.inner.as_fd()
}
}

#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
impl From<OwnedFd> 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 {
Expand Down Expand Up @@ -705,6 +727,33 @@ impl FromRawSocket for UdpSocket {
}
}

#[cfg(windows)]
impl From<UdpSocket> 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<OwnedSocket> 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<UdpSocket> for net::UdpSocket {
fn from(socket: UdpSocket) -> Self {
// Safety: This is safe since we are extracting the raw fd from a well-constructed
Expand Down
14 changes: 13 additions & 1 deletion src/net/uds/datagram.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -249,8 +249,20 @@ impl From<UnixDatagram> for net::UnixDatagram {
}
}

impl From<UnixDatagram> 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<OwnedFd> for UnixDatagram {
fn from(fd: OwnedFd) -> Self {
UnixDatagram::from_std(From::from(fd))
}
}
14 changes: 13 additions & 1 deletion src/net/uds/listener.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -118,8 +118,20 @@ impl From<UnixListener> for net::UnixListener {
}
}

impl From<UnixListener> 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<OwnedFd> for UnixListener {
fn from(fd: OwnedFd) -> Self {
UnixListener::from_std(From::from(fd))
}
}
14 changes: 13 additions & 1 deletion src/net/uds/stream.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -262,8 +262,20 @@ impl From<UnixStream> for net::UnixStream {
}
}

impl From<UnixStream> 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<OwnedFd> for UnixStream {
fn from(fd: OwnedFd) -> Self {
UnixStream::from_std(From::from(fd))
}
}
Loading

0 comments on commit d8d68ac

Please sign in to comment.