Skip to content

Implement stabilization of #[feature(io_safety)]. #95118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 15, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion library/std/src/os/fd/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Owned and borrowed Unix-like file descriptors.
#![unstable(feature = "io_safety", issue = "87074")]
#![stable(feature = "io_safety", since = "1.63.0")]
#![deny(unsafe_op_in_unsafe_fn)]

// `RawFd`, `AsRawFd`, etc.
62 changes: 32 additions & 30 deletions library/std/src/os/fd/owned.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Owned and borrowed Unix-like file descriptors.
#![unstable(feature = "io_safety", issue = "87074")]
#![stable(feature = "io_safety", since = "1.63.0")]
#![deny(unsafe_op_in_unsafe_fn)]

use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
@@ -33,7 +33,7 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
// because c_int is 32 bits.
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub struct BorrowedFd<'fd> {
fd: RawFd,
_phantom: PhantomData<&'fd OwnedFd>,
@@ -54,7 +54,7 @@ pub struct BorrowedFd<'fd> {
// because c_int is 32 bits.
#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub struct OwnedFd {
fd: RawFd,
}
@@ -67,7 +67,8 @@ impl BorrowedFd<'_> {
/// The resource pointed to by `fd` must remain open for the duration of
/// the returned `BorrowedFd`, and it must not have the value `-1`.
#[inline]
#[unstable(feature = "io_safety", issue = "87074")]
#[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub const unsafe fn borrow_raw(fd: RawFd) -> Self {
assert!(fd != u32::MAX as RawFd);
// SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned)
@@ -79,6 +80,7 @@ impl OwnedFd {
/// Creates a new `OwnedFd` instance that shares the same underlying file handle
/// as the existing `OwnedFd` instance.
#[cfg(not(target_arch = "wasm32"))]
#[stable(feature = "io_safety", since = "1.63.0")]
pub fn try_clone(&self) -> crate::io::Result<Self> {
// We want to atomically duplicate this file descriptor and set the
// CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This
@@ -98,6 +100,7 @@ impl OwnedFd {
}

#[cfg(target_arch = "wasm32")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub fn try_clone(&self) -> crate::io::Result<Self> {
Err(crate::io::const_io_error!(
crate::io::ErrorKind::Unsupported,
@@ -106,23 +109,23 @@ impl OwnedFd {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsRawFd for BorrowedFd<'_> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
self.fd
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsRawFd for OwnedFd {
#[inline]
fn as_raw_fd(&self) -> RawFd {
self.fd
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl IntoRawFd for OwnedFd {
#[inline]
fn into_raw_fd(self) -> RawFd {
@@ -132,7 +135,7 @@ impl IntoRawFd for OwnedFd {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl FromRawFd for OwnedFd {
/// Constructs a new instance of `Self` from the given raw file descriptor.
///
@@ -148,7 +151,7 @@ impl FromRawFd for OwnedFd {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl Drop for OwnedFd {
#[inline]
fn drop(&mut self) {
@@ -163,14 +166,14 @@ impl Drop for OwnedFd {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl fmt::Debug for BorrowedFd<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BorrowedFd").field("fd", &self.fd).finish()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl fmt::Debug for OwnedFd {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OwnedFd").field("fd", &self.fd).finish()
@@ -182,14 +185,13 @@ impl fmt::Debug for OwnedFd {
/// This is only available on unix platforms and must be imported in order to
/// call the method. Windows platforms have a corresponding `AsHandle` and
/// `AsSocket` set of traits.
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub trait AsFd {
/// Borrows the file descriptor.
///
/// # Example
///
/// ```rust,no_run
/// # #![feature(io_safety)]
/// use std::fs::File;
/// # use std::io;
/// # #[cfg(target_os = "wasi")]
@@ -202,35 +204,35 @@ pub trait AsFd {
/// let borrowed_fd: BorrowedFd<'_> = f.as_fd();
/// # Ok::<(), io::Error>(())
/// ```
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
fn as_fd(&self) -> BorrowedFd<'_>;
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl<T: AsFd> AsFd for &T {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
T::as_fd(self)
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl<T: AsFd> AsFd for &mut T {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
T::as_fd(self)
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for BorrowedFd<'_> {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
*self
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for OwnedFd {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
@@ -241,47 +243,47 @@ impl AsFd for OwnedFd {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for fs::File {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().as_fd()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<fs::File> for OwnedFd {
#[inline]
fn from(file: fs::File) -> OwnedFd {
file.into_inner().into_inner().into_inner()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedFd> for fs::File {
#[inline]
fn from(owned_fd: OwnedFd) -> Self {
Self::from_inner(FromInner::from_inner(FromInner::from_inner(owned_fd)))
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for crate::net::TcpStream {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().socket().as_fd()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::net::TcpStream> for OwnedFd {
#[inline]
fn from(tcp_stream: crate::net::TcpStream) -> OwnedFd {
tcp_stream.into_inner().into_socket().into_inner().into_inner().into()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedFd> for crate::net::TcpStream {
#[inline]
fn from(owned_fd: OwnedFd) -> Self {
@@ -291,23 +293,23 @@ impl From<OwnedFd> for crate::net::TcpStream {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for crate::net::TcpListener {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().socket().as_fd()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::net::TcpListener> for OwnedFd {
#[inline]
fn from(tcp_listener: crate::net::TcpListener) -> OwnedFd {
tcp_listener.into_inner().into_socket().into_inner().into_inner().into()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedFd> for crate::net::TcpListener {
#[inline]
fn from(owned_fd: OwnedFd) -> Self {
@@ -317,23 +319,23 @@ impl From<OwnedFd> for crate::net::TcpListener {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for crate::net::UdpSocket {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().socket().as_fd()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::net::UdpSocket> for OwnedFd {
#[inline]
fn from(udp_socket: crate::net::UdpSocket) -> OwnedFd {
udp_socket.into_inner().into_socket().into_inner().into_inner().into()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedFd> for crate::net::UdpSocket {
#[inline]
fn from(owned_fd: OwnedFd) -> Self {
3 changes: 1 addition & 2 deletions library/std/src/os/unix/io/fd.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//! Owned and borrowed file descriptors.
#![unstable(feature = "io_safety", issue = "87074")]

// Tests for this module
#[cfg(test)]
mod tests;

#[stable(feature = "io_safety", since = "1.63.0")]
pub use crate::os::fd::owned::*;
2 changes: 1 addition & 1 deletion library/std/src/os/unix/io/mod.rs
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@
mod fd;
mod raw;

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub use fd::*;
#[stable(feature = "rust1", since = "1.0.0")]
pub use raw::*;
6 changes: 3 additions & 3 deletions library/std/src/os/unix/net/datagram.rs
Original file line number Diff line number Diff line change
@@ -962,23 +962,23 @@ impl IntoRawFd for UnixDatagram {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for UnixDatagram {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_inner().as_fd()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<UnixDatagram> for OwnedFd {
#[inline]
fn from(unix_datagram: UnixDatagram) -> OwnedFd {
unsafe { OwnedFd::from_raw_fd(unix_datagram.into_raw_fd()) }
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedFd> for UnixDatagram {
#[inline]
fn from(owned: OwnedFd) -> Self {
6 changes: 3 additions & 3 deletions library/std/src/os/unix/net/listener.rs
Original file line number Diff line number Diff line change
@@ -300,23 +300,23 @@ impl IntoRawFd for UnixListener {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for UnixListener {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_inner().as_fd()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedFd> for UnixListener {
#[inline]
fn from(fd: OwnedFd) -> UnixListener {
UnixListener(Socket::from_inner(FromInner::from_inner(fd)))
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<UnixListener> for OwnedFd {
#[inline]
fn from(listener: UnixListener) -> OwnedFd {
6 changes: 3 additions & 3 deletions library/std/src/os/unix/net/stream.rs
Original file line number Diff line number Diff line change
@@ -683,23 +683,23 @@ impl IntoRawFd for UnixStream {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for UnixStream {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_fd()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<UnixStream> for OwnedFd {
#[inline]
fn from(unix_stream: UnixStream) -> OwnedFd {
unsafe { OwnedFd::from_raw_fd(unix_stream.into_raw_fd()) }
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedFd> for UnixStream {
#[inline]
fn from(owned: OwnedFd) -> Self {
14 changes: 7 additions & 7 deletions library/std/src/os/unix/process.rs
Original file line number Diff line number Diff line change
@@ -339,7 +339,7 @@ impl FromRawFd for process::Stdio {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedFd> for process::Stdio {
#[inline]
fn from(fd: OwnedFd) -> process::Stdio {
@@ -397,47 +397,47 @@ impl IntoRawFd for process::ChildStderr {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for crate::process::ChildStdin {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().as_fd()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::process::ChildStdin> for OwnedFd {
#[inline]
fn from(child_stdin: crate::process::ChildStdin) -> OwnedFd {
child_stdin.into_inner().into_inner().into_inner()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for crate::process::ChildStdout {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().as_fd()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::process::ChildStdout> for OwnedFd {
#[inline]
fn from(child_stdout: crate::process::ChildStdout) -> OwnedFd {
child_stdout.into_inner().into_inner().into_inner()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for crate::process::ChildStderr {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().as_fd()
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::process::ChildStderr> for OwnedFd {
#[inline]
fn from(child_stderr: crate::process::ChildStderr) -> OwnedFd {
72 changes: 56 additions & 16 deletions library/std/src/os/windows/io/handle.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Owned and borrowed OS handles.
#![unstable(feature = "io_safety", issue = "87074")]
#![stable(feature = "io_safety", since = "1.63.0")]

use super::raw::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
use crate::fmt;
@@ -38,7 +38,7 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
/// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks
#[derive(Copy, Clone)]
#[repr(transparent)]
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub struct BorrowedHandle<'handle> {
handle: RawHandle,
_phantom: PhantomData<&'handle OwnedHandle>,
@@ -66,7 +66,7 @@ pub struct BorrowedHandle<'handle> {
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
/// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks
#[repr(transparent)]
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub struct OwnedHandle {
handle: RawHandle,
}
@@ -89,7 +89,7 @@ pub struct OwnedHandle {
///
/// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks
#[repr(transparent)]
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
#[derive(Debug)]
pub struct HandleOrNull(OwnedHandle);

@@ -108,7 +108,7 @@ pub struct HandleOrNull(OwnedHandle);
///
/// If holds a handle other than `INVALID_HANDLE_VALUE`, it will close the handle on drop.
#[repr(transparent)]
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
#[derive(Debug)]
pub struct HandleOrInvalid(OwnedHandle);

@@ -117,13 +117,21 @@ pub struct HandleOrInvalid(OwnedHandle);
// `Send` or `Sync`).
//
// [`HANDLE`]: std::os::windows::raw::HANDLE
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Send for OwnedHandle {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Send for HandleOrNull {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Send for HandleOrInvalid {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Send for BorrowedHandle<'_> {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Sync for OwnedHandle {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Sync for HandleOrNull {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Sync for HandleOrInvalid {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Sync for BorrowedHandle<'_> {}

impl BorrowedHandle<'_> {
@@ -142,12 +150,14 @@ impl BorrowedHandle<'_> {
///
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
#[inline]
#[unstable(feature = "io_safety", issue = "87074")]
#[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub const unsafe fn borrow_raw(handle: RawHandle) -> Self {
Self { handle, _phantom: PhantomData }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl TryFrom<HandleOrNull> for OwnedHandle {
type Error = NullHandleError;

@@ -169,6 +179,7 @@ impl TryFrom<HandleOrNull> for OwnedHandle {
impl OwnedHandle {
/// Creates a new `OwnedHandle` instance that shares the same underlying file handle
/// as the existing `OwnedHandle` instance.
#[stable(feature = "io_safety", since = "1.63.0")]
pub fn try_clone(&self) -> crate::io::Result<Self> {
self.duplicate(0, false, c::DUPLICATE_SAME_ACCESS)
}
@@ -206,6 +217,7 @@ impl OwnedHandle {
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl TryFrom<HandleOrInvalid> for OwnedHandle {
type Error = InvalidHandleError;

@@ -227,53 +239,56 @@ impl TryFrom<HandleOrInvalid> for OwnedHandle {
/// This is the error type used by [`HandleOrNull`] when attempting to convert
/// into a handle, to indicate that the value is null.
// The empty field prevents constructing this, and allows extending it in the future.
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NullHandleError(());

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl fmt::Display for NullHandleError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
"A HandleOrNull could not be converted to a handle because it was null".fmt(fmt)
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl crate::error::Error for NullHandleError {}

/// This is the error type used by [`HandleOrInvalid`] when attempting to
/// convert into a handle, to indicate that the value is
/// `INVALID_HANDLE_VALUE`.
// The empty field prevents constructing this, and allows extending it in the future.
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InvalidHandleError(());

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl fmt::Display for InvalidHandleError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
"A HandleOrInvalid could not be converted to a handle because it was INVALID_HANDLE_VALUE"
.fmt(fmt)
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl crate::error::Error for InvalidHandleError {}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsRawHandle for BorrowedHandle<'_> {
#[inline]
fn as_raw_handle(&self) -> RawHandle {
self.handle
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsRawHandle for OwnedHandle {
#[inline]
fn as_raw_handle(&self) -> RawHandle {
self.handle
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl IntoRawHandle for OwnedHandle {
#[inline]
fn into_raw_handle(self) -> RawHandle {
@@ -283,6 +298,7 @@ impl IntoRawHandle for OwnedHandle {
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl FromRawHandle for OwnedHandle {
#[inline]
unsafe fn from_raw_handle(handle: RawHandle) -> Self {
@@ -305,6 +321,7 @@ impl HandleOrNull {
/// Windows APIs use null for errors; see [here] for the full story.
///
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
#[stable(feature = "io_safety", since = "1.63.0")]
#[inline]
pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
Self(OwnedHandle::from_raw_handle(handle))
@@ -327,12 +344,14 @@ impl HandleOrInvalid {
/// `INVALID_HANDLE_VALUE` for errors; see [here] for the full story.
///
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
#[stable(feature = "io_safety", since = "1.63.0")]
#[inline]
pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
Self(OwnedHandle::from_raw_handle(handle))
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl Drop for OwnedHandle {
#[inline]
fn drop(&mut self) {
@@ -342,27 +361,28 @@ impl Drop for OwnedHandle {
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl fmt::Debug for BorrowedHandle<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BorrowedHandle").field("handle", &self.handle).finish()
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl fmt::Debug for OwnedHandle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OwnedHandle").field("handle", &self.handle).finish()
}
}

/// A trait to borrow the handle from an underlying object.
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub trait AsHandle {
/// Borrows the handle.
///
/// # Example
///
/// ```rust,no_run
/// # #![feature(io_safety)]
/// use std::fs::File;
/// # use std::io;
/// use std::os::windows::io::{AsHandle, BorrowedHandle};
@@ -371,32 +391,35 @@ pub trait AsHandle {
/// let borrowed_handle: BorrowedHandle<'_> = f.as_handle();
/// # Ok::<(), io::Error>(())
/// ```
#[stable(feature = "io_safety", since = "1.63.0")]
fn as_handle(&self) -> BorrowedHandle<'_>;
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl<T: AsHandle> AsHandle for &T {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
T::as_handle(self)
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl<T: AsHandle> AsHandle for &mut T {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
T::as_handle(self)
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for BorrowedHandle<'_> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
*self
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for OwnedHandle {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -407,118 +430,135 @@ impl AsHandle for OwnedHandle {
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for fs::File {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
self.as_inner().as_handle()
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl From<fs::File> for OwnedHandle {
#[inline]
fn from(file: fs::File) -> OwnedHandle {
file.into_inner().into_inner().into_inner().into()
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedHandle> for fs::File {
#[inline]
fn from(owned: OwnedHandle) -> Self {
Self::from_inner(FromInner::from_inner(FromInner::from_inner(owned)))
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for crate::io::Stdin {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl<'a> AsHandle for crate::io::StdinLock<'a> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for crate::io::Stdout {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl<'a> AsHandle for crate::io::StdoutLock<'a> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for crate::io::Stderr {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl<'a> AsHandle for crate::io::StderrLock<'a> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for crate::process::ChildStdin {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::process::ChildStdin> for OwnedHandle {
#[inline]
fn from(child_stdin: crate::process::ChildStdin) -> OwnedHandle {
unsafe { OwnedHandle::from_raw_handle(child_stdin.into_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for crate::process::ChildStdout {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::process::ChildStdout> for OwnedHandle {
#[inline]
fn from(child_stdout: crate::process::ChildStdout) -> OwnedHandle {
unsafe { OwnedHandle::from_raw_handle(child_stdout.into_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for crate::process::ChildStderr {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::process::ChildStderr> for OwnedHandle {
#[inline]
fn from(child_stderr: crate::process::ChildStderr) -> OwnedHandle {
unsafe { OwnedHandle::from_raw_handle(child_stderr.into_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl<T> AsHandle for crate::thread::JoinHandle<T> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl<T> From<crate::thread::JoinHandle<T>> for OwnedHandle {
#[inline]
fn from(join_handle: crate::thread::JoinHandle<T>) -> OwnedHandle {
4 changes: 2 additions & 2 deletions library/std/src/os/windows/io/mod.rs
Original file line number Diff line number Diff line change
@@ -48,11 +48,11 @@ mod handle;
mod raw;
mod socket;

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub use handle::*;
#[stable(feature = "rust1", since = "1.0.0")]
pub use raw::*;
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub use socket::*;

#[cfg(test)]
35 changes: 28 additions & 7 deletions library/std/src/os/windows/io/socket.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Owned and borrowed OS sockets.
#![unstable(feature = "io_safety", issue = "87074")]
#![stable(feature = "io_safety", since = "1.63.0")]

use super::raw::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
use crate::fmt;
@@ -36,7 +36,7 @@ use crate::sys::cvt;
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
)]
#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub struct BorrowedSocket<'socket> {
socket: RawSocket,
_phantom: PhantomData<&'socket OwnedSocket>,
@@ -59,7 +59,7 @@ pub struct BorrowedSocket<'socket> {
rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FF_FF_FF_FF_FE)
)]
#[rustc_nonnull_optimization_guaranteed]
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub struct OwnedSocket {
socket: RawSocket,
}
@@ -73,7 +73,8 @@ impl BorrowedSocket<'_> {
/// the returned `BorrowedSocket`, and it must not have the value
/// `INVALID_SOCKET`.
#[inline]
#[unstable(feature = "io_safety", issue = "87074")]
#[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub const unsafe fn borrow_raw(socket: RawSocket) -> Self {
assert!(socket != c::INVALID_SOCKET as RawSocket);
Self { socket, _phantom: PhantomData }
@@ -83,6 +84,7 @@ impl BorrowedSocket<'_> {
impl OwnedSocket {
/// Creates a new `OwnedSocket` instance that shares the same underlying socket
/// as the existing `OwnedSocket` instance.
#[stable(feature = "io_safety", since = "1.63.0")]
pub fn try_clone(&self) -> io::Result<Self> {
let mut info = unsafe { mem::zeroed::<c::WSAPROTOCOL_INFO>() };
let result = unsafe {
@@ -152,20 +154,23 @@ fn last_error() -> io::Error {
io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsRawSocket for BorrowedSocket<'_> {
#[inline]
fn as_raw_socket(&self) -> RawSocket {
self.socket
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsRawSocket for OwnedSocket {
#[inline]
fn as_raw_socket(&self) -> RawSocket {
self.socket
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl IntoRawSocket for OwnedSocket {
#[inline]
fn into_raw_socket(self) -> RawSocket {
@@ -175,6 +180,7 @@ impl IntoRawSocket for OwnedSocket {
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl FromRawSocket for OwnedSocket {
#[inline]
unsafe fn from_raw_socket(socket: RawSocket) -> Self {
@@ -183,6 +189,7 @@ impl FromRawSocket for OwnedSocket {
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl Drop for OwnedSocket {
#[inline]
fn drop(&mut self) {
@@ -192,48 +199,53 @@ impl Drop for OwnedSocket {
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl fmt::Debug for BorrowedSocket<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BorrowedSocket").field("socket", &self.socket).finish()
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl fmt::Debug for OwnedSocket {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OwnedSocket").field("socket", &self.socket).finish()
}
}

/// A trait to borrow the socket from an underlying object.
#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub trait AsSocket {
/// Borrows the socket.
#[stable(feature = "io_safety", since = "1.63.0")]
fn as_socket(&self) -> BorrowedSocket<'_>;
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl<T: AsSocket> AsSocket for &T {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
T::as_socket(self)
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl<T: AsSocket> AsSocket for &mut T {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
T::as_socket(self)
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsSocket for BorrowedSocket<'_> {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
*self
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsSocket for OwnedSocket {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
@@ -244,62 +256,71 @@ impl AsSocket for OwnedSocket {
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsSocket for crate::net::TcpStream {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::net::TcpStream> for OwnedSocket {
#[inline]
fn from(tcp_stream: crate::net::TcpStream) -> OwnedSocket {
unsafe { OwnedSocket::from_raw_socket(tcp_stream.into_raw_socket()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedSocket> for crate::net::TcpStream {
#[inline]
fn from(owned: OwnedSocket) -> Self {
unsafe { Self::from_raw_socket(owned.into_raw_socket()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsSocket for crate::net::TcpListener {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::net::TcpListener> for OwnedSocket {
#[inline]
fn from(tcp_listener: crate::net::TcpListener) -> OwnedSocket {
unsafe { OwnedSocket::from_raw_socket(tcp_listener.into_raw_socket()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedSocket> for crate::net::TcpListener {
#[inline]
fn from(owned: OwnedSocket) -> Self {
unsafe { Self::from_raw_socket(owned.into_raw_socket()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl AsSocket for crate::net::UdpSocket {
#[inline]
fn as_socket(&self) -> BorrowedSocket<'_> {
unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::net::UdpSocket> for OwnedSocket {
#[inline]
fn from(udp_socket: crate::net::UdpSocket) -> OwnedSocket {
unsafe { OwnedSocket::from_raw_socket(udp_socket.into_raw_socket()) }
}
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedSocket> for crate::net::UdpSocket {
#[inline]
fn from(owned: OwnedSocket) -> Self {
6 changes: 3 additions & 3 deletions library/std/src/os/windows/process.rs
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ impl FromRawHandle for process::Stdio {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedHandle> for process::Stdio {
fn from(handle: OwnedHandle) -> process::Stdio {
let handle = sys::handle::Handle::from_inner(handle);
@@ -39,7 +39,7 @@ impl AsRawHandle for process::Child {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for process::Child {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -54,7 +54,7 @@ impl IntoRawHandle for process::Child {
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<process::Child> for OwnedHandle {
fn from(child: process::Child) -> OwnedHandle {
child.into_inner().into_handle().into_inner()
12 changes: 6 additions & 6 deletions library/std/src/sys/unix/stdio.rs
Original file line number Diff line number Diff line change
@@ -92,47 +92,47 @@ pub fn panic_output() -> Option<impl io::Write> {
Some(Stderr::new())
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for io::Stdin {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
unsafe { BorrowedFd::borrow_raw(libc::STDIN_FILENO) }
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl<'a> AsFd for io::StdinLock<'a> {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
unsafe { BorrowedFd::borrow_raw(libc::STDIN_FILENO) }
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for io::Stdout {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
unsafe { BorrowedFd::borrow_raw(libc::STDOUT_FILENO) }
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl<'a> AsFd for io::StdoutLock<'a> {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
unsafe { BorrowedFd::borrow_raw(libc::STDOUT_FILENO) }
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsFd for io::Stderr {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
unsafe { BorrowedFd::borrow_raw(libc::STDERR_FILENO) }
}
}

#[unstable(feature = "io_safety", issue = "87074")]
#[stable(feature = "io_safety", since = "1.63.0")]
impl<'a> AsFd for io::StderrLock<'a> {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {