Skip to content

Commit

Permalink
Auto merge of #87329 - sunfishcode:sunfishcode/io-safety, r=joshtriplett
Browse files Browse the repository at this point in the history
I/O safety.

Introduce `OwnedFd` and `BorrowedFd`, and the `AsFd` trait, and
implementations of `AsFd`, `From<OwnedFd>` and `From<T> for OwnedFd`
for relevant types, along with Windows counterparts for handles and
sockets.

Tracking issue: <#87074>

RFC: <https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md>

Highlights:
 - The doc comments at the top of library/std/src/os/unix/io/mod.rs and library/std/src/os/windows/io/mod.rs
 - The new types and traits in library/std/src/os/unix/io/fd.rs and library/std/src/os/windows/io/handle.rs
 - The removal of the `RawHandle` struct the Windows impl, which had the same name as the `RawHandle` type alias, and its functionality is now folded into `Handle`.

Managing five levels of wrapping (File wraps sys::fs::File wraps sys::fs::FileDesc wraps OwnedFd wraps RawFd, etc.) made for a fair amount of churn and verbose as/into/from sequences in some places. I've managed to simplify some of them, but I'm open to ideas here.

r? `@joshtriplett`
  • Loading branch information
bors committed Aug 20, 2021
2 parents 9ccf661 + b4dfa19 commit 5217347
Show file tree
Hide file tree
Showing 57 changed files with 2,229 additions and 711 deletions.
6 changes: 6 additions & 0 deletions library/std/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,12 @@ impl File {
}
}

// In addition to the `impl`s here, `File` also has `impl`s for
// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and
// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and
// `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and
// `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows.

impl AsInner<fs_imp::File> for File {
fn as_inner(&self) -> &fs_imp::File {
&self.inner
Expand Down
12 changes: 12 additions & 0 deletions library/std/src/net/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,12 @@ impl TcpStream {
}
}

// In addition to the `impl`s here, `TcpStream` also has `impl`s for
// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and
// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and
// `AsSocket`/`From<OwnedSocket>`/`Into<OwnedSocket>` and
// `AsRawSocket`/`IntoRawSocket`/`FromRawSocket` on Windows.

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for TcpStream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
Expand Down Expand Up @@ -915,6 +921,12 @@ impl TcpListener {
}
}

// In addition to the `impl`s here, `TcpListener` also has `impl`s for
// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and
// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and
// `AsSocket`/`From<OwnedSocket>`/`Into<OwnedSocket>` and
// `AsRawSocket`/`IntoRawSocket`/`FromRawSocket` on Windows.

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Iterator for Incoming<'a> {
type Item = io::Result<TcpStream>;
Expand Down
6 changes: 6 additions & 0 deletions library/std/src/net/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,12 @@ impl UdpSocket {
}
}

// In addition to the `impl`s here, `UdpSocket` also has `impl`s for
// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and
// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and
// `AsSocket`/`From<OwnedSocket>`/`Into<OwnedSocket>` and
// `AsRawSocket`/`IntoRawSocket`/`FromRawSocket` on Windows.

impl AsInner<net_imp::UdpSocket> for UdpSocket {
fn as_inner(&self) -> &net_imp::UdpSocket {
&self.0
Expand Down
3 changes: 1 addition & 2 deletions library/std/src/net/udp/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use crate::io::ErrorKind;
use crate::net::test::{next_test_ip4, next_test_ip6};
use crate::net::*;
use crate::sync::mpsc::channel;
use crate::sys_common::AsInner;
use crate::thread;
use crate::time::{Duration, Instant};

Expand Down Expand Up @@ -173,7 +172,7 @@ fn debug() {
let socket_addr = next_test_ip4();

let udpsock = t!(UdpSocket::bind(&socket_addr));
let udpsock_inner = udpsock.0.socket().as_inner();
let udpsock_inner = udpsock.0.socket().as_raw();
let compare = format!("UdpSocket {{ addr: {:?}, {}: {:?} }}", socket_addr, name, udpsock_inner);
assert_eq!(format!("{:?}", udpsock), compare);
}
Expand Down
13 changes: 13 additions & 0 deletions library/std/src/os/fd/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//! Owned and borrowed Unix-like file descriptors.
#![unstable(feature = "io_safety", issue = "87074")]
#![deny(unsafe_op_in_unsafe_fn)]

// `RawFd`, `AsRawFd`, etc.
pub mod raw;

// `OwnedFd`, `AsFd`, etc.
pub mod owned;

// Implementations for `AsRawFd` etc. for network types.
mod net;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::os::fd::owned::OwnedFd;
use crate::os::fd::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
use crate::{net, sys};

Expand All @@ -8,7 +9,7 @@ macro_rules! impl_as_raw_fd {
impl AsRawFd for net::$t {
#[inline]
fn as_raw_fd(&self) -> RawFd {
*self.as_inner().socket().as_inner()
self.as_inner().socket().as_raw_fd()
}
}
)*};
Expand All @@ -21,8 +22,10 @@ macro_rules! impl_from_raw_fd {
impl FromRawFd for net::$t {
#[inline]
unsafe fn from_raw_fd(fd: RawFd) -> net::$t {
let socket = sys::net::Socket::from_inner(fd);
net::$t::from_inner(sys_common::net::$t::from_inner(socket))
unsafe {
let socket = sys::net::Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd)));
net::$t::from_inner(sys_common::net::$t::from_inner(socket))
}
}
}
)*};
Expand All @@ -35,7 +38,7 @@ macro_rules! impl_into_raw_fd {
impl IntoRawFd for net::$t {
#[inline]
fn into_raw_fd(self) -> RawFd {
self.into_inner().into_socket().into_inner()
self.into_inner().into_socket().into_inner().into_inner().into_raw_fd()
}
}
)*};
Expand Down
Loading

0 comments on commit 5217347

Please sign in to comment.