From b5fb4f3d9b1b308d59cab24ef2f9bf23dad948aa Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 28 Jan 2023 23:42:08 +0100 Subject: move IO traits to std/src/os/hermit By moving the IO traits, the RustyHermit support is harmonized to of other operating systems. --- library/std/src/os/hermit/io.rs | 6 - library/std/src/os/hermit/io/mod.rs | 10 ++ library/std/src/os/hermit/io/owned.rs | 268 +++++++++++++++++++++++++++++++++ library/std/src/os/hermit/io/raw.rs | 115 ++++++++++++++ library/std/src/os/hermit/mod.rs | 5 + library/std/src/os/mod.rs | 12 +- library/std/src/sys/hermit/args.rs | 2 +- library/std/src/sys/hermit/fd.rs | 94 ++++++++++++ library/std/src/sys/hermit/fd/mod.rs | 97 ------------ library/std/src/sys/hermit/fd/owned.rs | 238 ----------------------------- library/std/src/sys/hermit/fd/raw.rs | 115 -------------- library/std/src/sys/hermit/fs.rs | 8 +- library/std/src/sys/hermit/mod.rs | 4 +- library/std/src/sys/hermit/net.rs | 3 +- library/std/src/sys/hermit/os.rs | 2 +- 15 files changed, 504 insertions(+), 475 deletions(-) delete mode 100644 library/std/src/os/hermit/io.rs create mode 100644 library/std/src/os/hermit/io/mod.rs create mode 100644 library/std/src/os/hermit/io/owned.rs create mode 100644 library/std/src/os/hermit/io/raw.rs create mode 100644 library/std/src/sys/hermit/fd.rs delete mode 100644 library/std/src/sys/hermit/fd/mod.rs delete mode 100644 library/std/src/sys/hermit/fd/owned.rs delete mode 100644 library/std/src/sys/hermit/fd/raw.rs (limited to 'library/std') diff --git a/library/std/src/os/hermit/io.rs b/library/std/src/os/hermit/io.rs deleted file mode 100644 index d8c741f7f4e..00000000000 --- a/library/std/src/os/hermit/io.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![stable(feature = "rust1", since = "1.0.0")] - -use hermit_abi as abi; - -#[stable(feature = "rust1", since = "1.0.0")] -pub type RawFd = abi::FileDescriptor; diff --git a/library/std/src/os/hermit/io/mod.rs b/library/std/src/os/hermit/io/mod.rs new file mode 100644 index 00000000000..f2091672801 --- /dev/null +++ b/library/std/src/os/hermit/io/mod.rs @@ -0,0 +1,10 @@ +#![stable(feature = "os_fd", since = "1.66.0")] + +mod owned; +mod raw; + +// Export the types and traits for the public API. +#[stable(feature = "os_fd", since = "1.66.0")] +pub use owned::*; +#[stable(feature = "os_fd", since = "1.66.0")] +pub use raw::*; diff --git a/library/std/src/os/hermit/io/owned.rs b/library/std/src/os/hermit/io/owned.rs new file mode 100644 index 00000000000..4add29b1374 --- /dev/null +++ b/library/std/src/os/hermit/io/owned.rs @@ -0,0 +1,268 @@ +use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; +use crate::fmt; +use crate::marker::PhantomData; +use crate::mem::forget; +use crate::os::hermit::abi; +use crate::sys_common::{AsInner, FromInner, IntoInner}; + +/// A borrowed file descriptor. +/// +/// This has a lifetime parameter to tie it to the lifetime of something that +/// owns the file descriptor. +/// +/// This uses `repr(transparent)` and has the representation of a host file +/// descriptor, so it can be used in FFI in places where a file descriptor is +/// passed as an argument, it is not captured or consumed, and it never has the +/// value `-1`. +/// +/// This type's `.to_owned()` implementation returns another `BorrowedFd` +/// rather than an `OwnedFd`. It just makes a trivial copy of the raw file +/// descriptor, which is then borrowed under the same lifetime. +#[derive(Copy, Clone)] +#[repr(transparent)] +#[rustc_layout_scalar_valid_range_start(0)] +// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a +// 32-bit c_int. Below is -2, in two's complement, but that only works out +// because c_int is 32 bits. +#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] +#[rustc_nonnull_optimization_guaranteed] +#[stable(feature = "io_safety", since = "1.63.0")] +pub struct BorrowedFd<'fd> { + fd: RawFd, + _phantom: PhantomData<&'fd OwnedFd>, +} + +/// An owned file descriptor. +/// +/// This closes the file descriptor on drop. +/// +/// This uses `repr(transparent)` and has the representation of a host file +/// descriptor, so it can be used in FFI in places where a file descriptor is +/// passed as a consumed argument or returned as an owned value, and it never +/// has the value `-1`. +#[repr(transparent)] +#[rustc_layout_scalar_valid_range_start(0)] +// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a +// 32-bit c_int. Below is -2, in two's complement, but that only works out +// because c_int is 32 bits. +#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] +#[rustc_nonnull_optimization_guaranteed] +#[stable(feature = "io_safety", since = "1.63.0")] +pub struct OwnedFd { + fd: RawFd, +} + +impl BorrowedFd<'_> { + /// Return a `BorrowedFd` holding the given raw file descriptor. + /// + /// # Safety + /// + /// 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] + #[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) + unsafe { Self { fd, _phantom: PhantomData } } + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl Drop for OwnedFd { + #[inline] + fn drop(&mut self) { + unsafe { + // Note that errors are ignored when closing a file descriptor. The + // reason for this is that if an error occurs we don't actually know if + // the file descriptor was closed or not, and if we retried (for + // something like EINTR), we might close another valid file descriptor + // opened after we closed ours. + let _ = abi::close(self.fd); + } + } +} + +#[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() + } +} + +#[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() + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl AsRawFd for BorrowedFd<'_> { + #[inline] + fn as_raw_fd(&self) -> RawFd { + self.fd + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl AsRawFd for OwnedFd { + #[inline] + fn as_raw_fd(&self) -> RawFd { + self.fd + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl IntoRawFd for OwnedFd { + #[inline] + fn into_raw_fd(self) -> RawFd { + let fd = self.fd; + forget(self); + fd + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl FromRawFd for OwnedFd { + /// Constructs a new instance of `Self` from the given raw file descriptor. + /// + /// # Safety + /// + /// The resource pointed to by `fd` must be open and suitable for assuming + /// ownership. The resource must not require any cleanup other than `close`. + #[inline] + unsafe fn from_raw_fd(fd: RawFd) -> Self { + assert_ne!(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) + unsafe { Self { fd } } + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl From for OwnedFd { + #[inline] + fn from(tcp_stream: crate::net::TcpStream) -> OwnedFd { + tcp_stream.into_inner().into_socket().into_inner().into_inner().into() + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl From for crate::net::TcpStream { + #[inline] + fn from(owned_fd: OwnedFd) -> Self { + Self::from_inner(FromInner::from_inner(FromInner::from_inner(FromInner::from_inner( + owned_fd, + )))) + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl From for OwnedFd { + #[inline] + fn from(tcp_listener: crate::net::TcpListener) -> OwnedFd { + tcp_listener.into_inner().into_socket().into_inner().into_inner().into() + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl From for crate::net::TcpListener { + #[inline] + fn from(owned_fd: OwnedFd) -> Self { + Self::from_inner(FromInner::from_inner(FromInner::from_inner(FromInner::from_inner( + owned_fd, + )))) + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl From for OwnedFd { + #[inline] + fn from(udp_socket: crate::net::UdpSocket) -> OwnedFd { + udp_socket.into_inner().into_socket().into_inner().into_inner().into() + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl From for crate::net::UdpSocket { + #[inline] + fn from(owned_fd: OwnedFd) -> Self { + Self::from_inner(FromInner::from_inner(FromInner::from_inner(FromInner::from_inner( + owned_fd, + )))) + } +} + +/// A trait to borrow the file descriptor from an underlying object. +#[stable(feature = "io_safety", since = "1.63.0")] +pub trait AsFd { + /// Borrows the file descriptor. + /// + /// # Example + /// + /// ```rust,no_run + /// use std::fs::File; + /// # use std::io; + /// # #[cfg(any(unix, target_os = "wasi"))] + /// # use std::os::fd::{AsFd, BorrowedFd}; + /// + /// let mut f = File::open("foo.txt")?; + /// # #[cfg(any(unix, target_os = "wasi"))] + /// let borrowed_fd: BorrowedFd<'_> = f.as_fd(); + /// # Ok::<(), io::Error>(()) + /// ``` + #[stable(feature = "io_safety", since = "1.63.0")] + fn as_fd(&self) -> BorrowedFd<'_>; +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl AsFd for &T { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + T::as_fd(self) + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl AsFd for &mut T { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + T::as_fd(self) + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl AsFd for OwnedFd { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + // Safety: `OwnedFd` and `BorrowedFd` have the same validity + // invariants, and the `BorrowdFd` is bounded by the lifetime + // of `&self`. + unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) } + } +} + +#[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() + } +} + +#[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() + } +} + +#[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() + } +} diff --git a/library/std/src/os/hermit/io/raw.rs b/library/std/src/os/hermit/io/raw.rs new file mode 100644 index 00000000000..cdec90b4b87 --- /dev/null +++ b/library/std/src/os/hermit/io/raw.rs @@ -0,0 +1,115 @@ +/// Raw file descriptors. +#[rustc_allowed_through_unstable_modules] +#[stable(feature = "rust1", since = "1.0.0")] +pub type RawFd = i32; + +/// A trait to extract the raw file descriptor from an underlying object. +/// +/// This is only available on unix and WASI platforms and must be imported in +/// order to call the method. Windows platforms have a corresponding +/// `AsRawHandle` and `AsRawSocket` set of traits. +#[rustc_allowed_through_unstable_modules] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait AsRawFd { + /// Extracts the raw file descriptor. + /// + /// This function is typically used to **borrow** an owned file descriptor. + /// When used in this way, this method does **not** pass ownership of the + /// raw file descriptor to the caller, and the file descriptor is only + /// guaranteed to be valid while the original object has not yet been + /// destroyed. + /// + /// However, borrowing is not strictly required. See [`AsFd::as_fd`] + /// for an API which strictly borrows a file descriptor. + /// + /// # Example + /// + /// ```no_run + /// use std::fs::File; + /// # use std::io; + /// #[cfg(any(unix, target_os = "wasi"))] + /// use std::os::fd::{AsRawFd, RawFd}; + /// + /// let mut f = File::open("foo.txt")?; + /// // Note that `raw_fd` is only valid as long as `f` exists. + /// #[cfg(any(unix, target_os = "wasi"))] + /// let raw_fd: RawFd = f.as_raw_fd(); + /// # Ok::<(), io::Error>(()) + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn as_raw_fd(&self) -> RawFd; +} + +/// A trait to express the ability to consume an object and acquire ownership of +/// its raw file descriptor. +#[rustc_allowed_through_unstable_modules] +#[stable(feature = "into_raw_os", since = "1.4.0")] +pub trait IntoRawFd { + /// Consumes this object, returning the raw underlying file descriptor. + /// + /// This function is typically used to **transfer ownership** of the underlying + /// file descriptor to the caller. When used in this way, callers are then the unique + /// owners of the file descriptor and must close it once it's no longer needed. + /// + /// However, transferring ownership is not strictly required. Use a + /// [`Into::into`] implementation for an API which strictly + /// transfers ownership. + /// + /// # Example + /// + /// ```no_run + /// use std::fs::File; + /// # use std::io; + /// #[cfg(any(unix, target_os = "wasi"))] + /// use std::os::fd::{IntoRawFd, RawFd}; + /// + /// let f = File::open("foo.txt")?; + /// #[cfg(any(unix, target_os = "wasi"))] + /// let raw_fd: RawFd = f.into_raw_fd(); + /// # Ok::<(), io::Error>(()) + /// ``` + #[stable(feature = "into_raw_os", since = "1.4.0")] + fn into_raw_fd(self) -> RawFd; +} + +/// A trait to express the ability to construct an object from a raw file +/// descriptor. +#[rustc_allowed_through_unstable_modules] +#[stable(feature = "from_raw_os", since = "1.1.0")] +pub trait FromRawFd { + /// Constructs a new instance of `Self` from the given raw file + /// descriptor. + /// + /// This function is typically used to **consume ownership** of the + /// specified file descriptor. When used in this way, the returned object + /// will take responsibility for closing it when the object goes out of + /// scope. + /// + /// However, consuming ownership is not strictly required. Use a + /// [`From::from`] implementation for an API which strictly + /// consumes ownership. + /// + /// # Safety + /// + /// The `fd` passed in must be a valid and open file descriptor. + /// + /// # Example + /// + /// ```no_run + /// use std::fs::File; + /// # use std::io; + /// #[cfg(any(unix, target_os = "wasi"))] + /// use std::os::fd::{FromRawFd, IntoRawFd, RawFd}; + /// + /// let f = File::open("foo.txt")?; + /// # #[cfg(any(unix, target_os = "wasi"))] + /// let raw_fd: RawFd = f.into_raw_fd(); + /// // SAFETY: no other functions should call `from_raw_fd`, so there + /// // is only one owner for the file descriptor. + /// # #[cfg(any(unix, target_os = "wasi"))] + /// let f = unsafe { File::from_raw_fd(raw_fd) }; + /// # Ok::<(), io::Error>(()) + /// ``` + #[stable(feature = "from_raw_os", since = "1.1.0")] + unsafe fn from_raw_fd(fd: RawFd) -> Self; +} diff --git a/library/std/src/os/hermit/mod.rs b/library/std/src/os/hermit/mod.rs index 4657b545a1b..89b1b831912 100644 --- a/library/std/src/os/hermit/mod.rs +++ b/library/std/src/os/hermit/mod.rs @@ -1,6 +1,11 @@ #![stable(feature = "rust1", since = "1.0.0")] +#[allow(unused_extern_crates)] +#[stable(feature = "rust1", since = "1.0.0")] +pub extern crate hermit_abi as abi; + pub mod ffi; +pub mod io; /// A prelude for conveniently writing platform-specific code. /// diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 42773805cdb..af137c9bd85 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -60,16 +60,6 @@ pub mod windows {} all(target_vendor = "fortanix", target_env = "sgx") ) )))] -#[cfg(target_os = "hermit")] -#[path = "hermit/mod.rs"] -pub mod unix; -#[cfg(not(all( - doc, - any( - all(target_arch = "wasm32", not(target_os = "wasi")), - all(target_vendor = "fortanix", target_env = "sgx") - ) -)))] #[cfg(all(not(target_os = "hermit"), any(unix, doc)))] pub mod unix; @@ -123,6 +113,8 @@ pub mod freebsd; pub mod fuchsia; #[cfg(target_os = "haiku")] pub mod haiku; +#[cfg(target_os = "hermit")] +pub mod hermit; #[cfg(target_os = "horizon")] pub mod horizon; #[cfg(target_os = "illumos")] diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs index afcae6c90ee..220a76e4b12 100644 --- a/library/std/src/sys/hermit/args.rs +++ b/library/std/src/sys/hermit/args.rs @@ -1,6 +1,6 @@ use crate::ffi::{c_char, CStr, OsString}; use crate::fmt; -use crate::os::unix::ffi::OsStringExt; +use crate::os::hermit::ffi::OsStringExt; use crate::ptr; use crate::sync::atomic::{ AtomicIsize, AtomicPtr, diff --git a/library/std/src/sys/hermit/fd.rs b/library/std/src/sys/hermit/fd.rs new file mode 100644 index 00000000000..ea981b9fa97 --- /dev/null +++ b/library/std/src/sys/hermit/fd.rs @@ -0,0 +1,94 @@ +#![unstable(reason = "not public", issue = "none", feature = "fd")] + +use crate::io::{self, Read}; +use crate::os::hermit::io::{FromRawFd, OwnedFd, RawFd}; +use crate::sys::cvt; +use crate::sys::hermit::abi; +use crate::sys::unsupported; +use crate::sys_common::{AsInner, FromInner, IntoInner}; + +use crate::os::hermit::io::*; + +#[derive(Debug)] +pub struct FileDesc { + fd: OwnedFd, +} + +impl FileDesc { + pub fn read(&self, buf: &mut [u8]) -> io::Result { + let result = cvt(unsafe { abi::read(self.fd.as_raw_fd(), buf.as_mut_ptr(), buf.len()) })?; + Ok(result as usize) + } + + pub fn read_to_end(&self, buf: &mut Vec) -> io::Result { + let mut me = self; + (&mut me).read_to_end(buf) + } + + pub fn write(&self, buf: &[u8]) -> io::Result { + let result = cvt(unsafe { abi::write(self.fd.as_raw_fd(), buf.as_ptr(), buf.len()) })?; + Ok(result as usize) + } + + pub fn duplicate(&self) -> io::Result { + self.duplicate_path(&[]) + } + pub fn duplicate_path(&self, _path: &[u8]) -> io::Result { + unsupported() + } + + pub fn nonblocking(&self) -> io::Result { + Ok(false) + } + + pub fn set_cloexec(&self) -> io::Result<()> { + unsupported() + } + + pub fn set_nonblocking(&self, _nonblocking: bool) -> io::Result<()> { + unsupported() + } +} + +impl<'a> Read for &'a FileDesc { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + (**self).read(buf) + } +} + +impl IntoInner for FileDesc { + fn into_inner(self) -> OwnedFd { + self.fd + } +} + +impl FromInner for FileDesc { + fn from_inner(owned_fd: OwnedFd) -> Self { + Self { fd: owned_fd } + } +} + +impl FromRawFd for FileDesc { + unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + Self { fd: FromRawFd::from_raw_fd(raw_fd) } + } +} + +impl AsInner for FileDesc { + fn as_inner(&self) -> &OwnedFd { + &self.fd + } +} + +impl AsFd for FileDesc { + fn as_fd(&self) -> BorrowedFd<'_> { + self.fd.as_fd() + } +} + +impl AsRawFd for FileDesc { + #[inline] + fn as_raw_fd(&self) -> RawFd { + self.fd.as_raw_fd() + } +} diff --git a/library/std/src/sys/hermit/fd/mod.rs b/library/std/src/sys/hermit/fd/mod.rs deleted file mode 100644 index 7f3c7ea1030..00000000000 --- a/library/std/src/sys/hermit/fd/mod.rs +++ /dev/null @@ -1,97 +0,0 @@ -#![unstable(reason = "not public", issue = "none", feature = "fd")] - -mod owned; -mod raw; - -use crate::io::{self, Read}; -use crate::sys::cvt; -use crate::sys::hermit::abi; -use crate::sys::unsupported; -use crate::sys_common::{AsInner, FromInner, IntoInner}; - -pub use self::owned::*; -pub use self::raw::*; - -#[derive(Debug)] -pub struct FileDesc { - fd: OwnedFd, -} - -impl FileDesc { - pub fn read(&self, buf: &mut [u8]) -> io::Result { - let result = cvt(unsafe { abi::read(self.fd.as_raw_fd(), buf.as_mut_ptr(), buf.len()) })?; - Ok(result as usize) - } - - pub fn read_to_end(&self, buf: &mut Vec) -> io::Result { - let mut me = self; - (&mut me).read_to_end(buf) - } - - pub fn write(&self, buf: &[u8]) -> io::Result { - let result = cvt(unsafe { abi::write(self.fd.as_raw_fd(), buf.as_ptr(), buf.len()) })?; - Ok(result as usize) - } - - pub fn duplicate(&self) -> io::Result { - self.duplicate_path(&[]) - } - pub fn duplicate_path(&self, _path: &[u8]) -> io::Result { - unsupported() - } - - pub fn nonblocking(&self) -> io::Result { - Ok(false) - } - - pub fn set_cloexec(&self) -> io::Result<()> { - unsupported() - } - - pub fn set_nonblocking(&self, _nonblocking: bool) -> io::Result<()> { - unsupported() - } -} - -impl<'a> Read for &'a FileDesc { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - (**self).read(buf) - } -} - -impl IntoInner for FileDesc { - fn into_inner(self) -> OwnedFd { - self.fd - } -} - -impl FromInner for FileDesc { - fn from_inner(owned_fd: OwnedFd) -> Self { - Self { fd: owned_fd } - } -} - -impl FromRawFd for FileDesc { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - Self { fd: FromRawFd::from_raw_fd(raw_fd) } - } -} - -impl AsInner for FileDesc { - fn as_inner(&self) -> &OwnedFd { - &self.fd - } -} - -impl AsFd for FileDesc { - fn as_fd(&self) -> BorrowedFd<'_> { - self.fd.as_fd() - } -} - -impl AsRawFd for FileDesc { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.fd.as_raw_fd() - } -} diff --git a/library/std/src/sys/hermit/fd/owned.rs b/library/std/src/sys/hermit/fd/owned.rs deleted file mode 100644 index 7746cb3b259..00000000000 --- a/library/std/src/sys/hermit/fd/owned.rs +++ /dev/null @@ -1,238 +0,0 @@ -use super::raw::RawFd; - -use crate::marker::PhantomData; -use crate::mem::forget; -use crate::sys::fd::{AsRawFd, FromRawFd, IntoRawFd}; -use crate::sys::hermit::abi; -use crate::sys_common::{AsInner, FromInner, IntoInner}; - -/// A borrowed file descriptor. -/// -/// This has a lifetime parameter to tie it to the lifetime of something that -/// owns the file descriptor. -/// -/// This uses `repr(transparent)` and has the representation of a host file -/// descriptor, so it can be used in FFI in places where a file descriptor is -/// passed as an argument, it is not captured or consumed, and it never has the -/// value `-1`. -/// -/// This type's `.to_owned()` implementation returns another `BorrowedFd` -/// rather than an `OwnedFd`. It just makes a trivial copy of the raw file -/// descriptor, which is then borrowed under the same lifetime. -#[derive(Copy, Clone)] -#[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] -// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a -// 32-bit c_int. Below is -2, in two's complement, but that only works out -// because c_int is 32 bits. -#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] -#[rustc_nonnull_optimization_guaranteed] -#[stable(feature = "io_safety", since = "1.63.0")] -pub struct BorrowedFd<'fd> { - fd: RawFd, - _phantom: PhantomData<&'fd OwnedFd>, -} - -/// An owned file descriptor. -/// -/// This closes the file descriptor on drop. -/// -/// This uses `repr(transparent)` and has the representation of a host file -/// descriptor, so it can be used in FFI in places where a file descriptor is -/// passed as a consumed argument or returned as an owned value, and it never -/// has the value `-1`. -#[repr(transparent)] -#[rustc_layout_scalar_valid_range_start(0)] -// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a -// 32-bit c_int. Below is -2, in two's complement, but that only works out -// because c_int is 32 bits. -#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)] -#[rustc_nonnull_optimization_guaranteed] -#[stable(feature = "io_safety", since = "1.63.0")] -#[derive(Debug)] -pub struct OwnedFd { - fd: RawFd, -} - -impl BorrowedFd<'_> { - /// Return a `BorrowedFd` holding the given raw file descriptor. - /// - /// # Safety - /// - /// 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] - #[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) - unsafe { Self { fd, _phantom: PhantomData } } - } -} - -#[stable(feature = "io_safety", since = "1.63.0")] -impl AsRawFd for BorrowedFd<'_> { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.fd - } -} - -#[stable(feature = "io_safety", since = "1.63.0")] -impl AsRawFd for OwnedFd { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.fd - } -} - -#[stable(feature = "io_safety", since = "1.63.0")] -impl IntoRawFd for OwnedFd { - #[inline] - fn into_raw_fd(self) -> RawFd { - let fd = self.fd; - forget(self); - fd - } -} - -#[stable(feature = "io_safety", since = "1.63.0")] -impl FromRawFd for OwnedFd { - /// Constructs a new instance of `Self` from the given raw file descriptor. - /// - /// # Safety - /// - /// The resource pointed to by `fd` must be open and suitable for assuming - /// ownership. The resource must not require any cleanup other than `close`. - #[inline] - unsafe fn from_raw_fd(fd: RawFd) -> Self { - assert_ne!(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) - unsafe { Self { fd } } - } -} - -#[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() - } -} - -#[stable(feature = "io_safety", since = "1.63.0")] -impl From for OwnedFd { - #[inline] - fn from(tcp_stream: crate::net::TcpStream) -> OwnedFd { - tcp_stream.into_inner().into_socket().into_inner().into_inner().into() - } -} - -#[stable(feature = "io_safety", since = "1.63.0")] -impl From for crate::net::TcpStream { - #[inline] - fn from(owned_fd: OwnedFd) -> Self { - Self::from_inner(FromInner::from_inner(FromInner::from_inner(FromInner::from_inner( - owned_fd, - )))) - } -} - -#[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() - } -} - -#[stable(feature = "io_safety", since = "1.63.0")] -impl From for OwnedFd { - #[inline] - fn from(tcp_listener: crate::net::TcpListener) -> OwnedFd { - tcp_listener.into_inner().into_socket().into_inner().into_inner().into() - } -} - -#[stable(feature = "io_safety", since = "1.63.0")] -impl From for crate::net::TcpListener { - #[inline] - fn from(owned_fd: OwnedFd) -> Self { - Self::from_inner(FromInner::from_inner(FromInner::from_inner(FromInner::from_inner( - owned_fd, - )))) - } -} - -#[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() - } -} - -#[stable(feature = "io_safety", since = "1.63.0")] -impl From for OwnedFd { - #[inline] - fn from(udp_socket: crate::net::UdpSocket) -> OwnedFd { - udp_socket.into_inner().into_socket().into_inner().into_inner().into() - } -} - -#[stable(feature = "io_safety", since = "1.63.0")] -impl From for crate::net::UdpSocket { - #[inline] - fn from(owned_fd: OwnedFd) -> Self { - Self::from_inner(FromInner::from_inner(FromInner::from_inner(FromInner::from_inner( - owned_fd, - )))) - } -} - -#[stable(feature = "io_safety", since = "1.63.0")] -impl Drop for OwnedFd { - #[inline] - fn drop(&mut self) { - unsafe { - // Note that errors are ignored when closing a file descriptor. The - // reason for this is that if an error occurs we don't actually know if - // the file descriptor was closed or not, and if we retried (for - // something like EINTR), we might close another valid file descriptor - // opened after we closed ours. - let _ = abi::close(self.fd); - } - } -} - -pub trait AsFd { - /// Borrows the file descriptor. - /// - /// # Example - /// - /// ```rust,no_run - /// use std::fs::File; - /// # use std::io; - /// # #[cfg(any(unix, target_os = "wasi"))] - /// # use std::os::fd::{AsFd, BorrowedFd}; - /// - /// let mut f = File::open("foo.txt")?; - /// # #[cfg(any(unix, target_os = "wasi"))] - /// let borrowed_fd: BorrowedFd<'_> = f.as_fd(); - /// # Ok::<(), io::Error>(()) - /// ``` - #[stable(feature = "io_safety", since = "1.63.0")] - fn as_fd(&self) -> BorrowedFd<'_>; -} - -#[stable(feature = "io_safety", since = "1.63.0")] -impl AsFd for OwnedFd { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - // Safety: `OwnedFd` and `BorrowedFd` have the same validity - // invariants, and the `BorrowdFd` is bounded by the lifetime - // of `&self`. - unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) } - } -} diff --git a/library/std/src/sys/hermit/fd/raw.rs b/library/std/src/sys/hermit/fd/raw.rs deleted file mode 100644 index cdec90b4b87..00000000000 --- a/library/std/src/sys/hermit/fd/raw.rs +++ /dev/null @@ -1,115 +0,0 @@ -/// Raw file descriptors. -#[rustc_allowed_through_unstable_modules] -#[stable(feature = "rust1", since = "1.0.0")] -pub type RawFd = i32; - -/// A trait to extract the raw file descriptor from an underlying object. -/// -/// This is only available on unix and WASI platforms and must be imported in -/// order to call the method. Windows platforms have a corresponding -/// `AsRawHandle` and `AsRawSocket` set of traits. -#[rustc_allowed_through_unstable_modules] -#[stable(feature = "rust1", since = "1.0.0")] -pub trait AsRawFd { - /// Extracts the raw file descriptor. - /// - /// This function is typically used to **borrow** an owned file descriptor. - /// When used in this way, this method does **not** pass ownership of the - /// raw file descriptor to the caller, and the file descriptor is only - /// guaranteed to be valid while the original object has not yet been - /// destroyed. - /// - /// However, borrowing is not strictly required. See [`AsFd::as_fd`] - /// for an API which strictly borrows a file descriptor. - /// - /// # Example - /// - /// ```no_run - /// use std::fs::File; - /// # use std::io; - /// #[cfg(any(unix, target_os = "wasi"))] - /// use std::os::fd::{AsRawFd, RawFd}; - /// - /// let mut f = File::open("foo.txt")?; - /// // Note that `raw_fd` is only valid as long as `f` exists. - /// #[cfg(any(unix, target_os = "wasi"))] - /// let raw_fd: RawFd = f.as_raw_fd(); - /// # Ok::<(), io::Error>(()) - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn as_raw_fd(&self) -> RawFd; -} - -/// A trait to express the ability to consume an object and acquire ownership of -/// its raw file descriptor. -#[rustc_allowed_through_unstable_modules] -#[stable(feature = "into_raw_os", since = "1.4.0")] -pub trait IntoRawFd { - /// Consumes this object, returning the raw underlying file descriptor. - /// - /// This function is typically used to **transfer ownership** of the underlying - /// file descriptor to the caller. When used in this way, callers are then the unique - /// owners of the file descriptor and must close it once it's no longer needed. - /// - /// However, transferring ownership is not strictly required. Use a - /// [`Into::into`] implementation for an API which strictly - /// transfers ownership. - /// - /// # Example - /// - /// ```no_run - /// use std::fs::File; - /// # use std::io; - /// #[cfg(any(unix, target_os = "wasi"))] - /// use std::os::fd::{IntoRawFd, RawFd}; - /// - /// let f = File::open("foo.txt")?; - /// #[cfg(any(unix, target_os = "wasi"))] - /// let raw_fd: RawFd = f.into_raw_fd(); - /// # Ok::<(), io::Error>(()) - /// ``` - #[stable(feature = "into_raw_os", since = "1.4.0")] - fn into_raw_fd(self) -> RawFd; -} - -/// A trait to express the ability to construct an object from a raw file -/// descriptor. -#[rustc_allowed_through_unstable_modules] -#[stable(feature = "from_raw_os", since = "1.1.0")] -pub trait FromRawFd { - /// Constructs a new instance of `Self` from the given raw file - /// descriptor. - /// - /// This function is typically used to **consume ownership** of the - /// specified file descriptor. When used in this way, the returned object - /// will take responsibility for closing it when the object goes out of - /// scope. - /// - /// However, consuming ownership is not strictly required. Use a - /// [`From::from`] implementation for an API which strictly - /// consumes ownership. - /// - /// # Safety - /// - /// The `fd` passed in must be a valid and open file descriptor. - /// - /// # Example - /// - /// ```no_run - /// use std::fs::File; - /// # use std::io; - /// #[cfg(any(unix, target_os = "wasi"))] - /// use std::os::fd::{FromRawFd, IntoRawFd, RawFd}; - /// - /// let f = File::open("foo.txt")?; - /// # #[cfg(any(unix, target_os = "wasi"))] - /// let raw_fd: RawFd = f.into_raw_fd(); - /// // SAFETY: no other functions should call `from_raw_fd`, so there - /// // is only one owner for the file descriptor. - /// # #[cfg(any(unix, target_os = "wasi"))] - /// let f = unsafe { File::from_raw_fd(raw_fd) }; - /// # Ok::<(), io::Error>(()) - /// ``` - #[stable(feature = "from_raw_os", since = "1.1.0")] - unsafe fn from_raw_fd(fd: RawFd) -> Self; -} diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs index 6ae44484bce..cf9f9e06264 100644 --- a/library/std/src/sys/hermit/fs.rs +++ b/library/std/src/sys/hermit/fs.rs @@ -3,12 +3,14 @@ use crate::fmt; use crate::hash::{Hash, Hasher}; use crate::io::{self, Error, ErrorKind}; use crate::io::{BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; +use crate::os::hermit::io::FromRawFd; use crate::path::{Path, PathBuf}; use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::cvt; -use crate::sys::hermit::abi; -use crate::sys::hermit::abi::{O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY}; -use crate::sys::hermit::fd::{FileDesc, FromRawFd}; +use crate::sys::hermit::abi::{ + self, O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, +}; +use crate::sys::hermit::fd::FileDesc; use crate::sys::time::SystemTime; use crate::sys::unsupported; diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index a5956194eec..d34a4cfedea 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -57,9 +57,7 @@ pub mod locks { } use crate::io::ErrorKind; - -#[allow(unused_extern_crates)] -pub extern crate hermit_abi as abi; +use crate::os::hermit::abi; pub fn unsupported() -> crate::io::Result { Err(unsupported_err()) diff --git a/library/std/src/sys/hermit/net.rs b/library/std/src/sys/hermit/net.rs index 2d92068bca6..5fb6281aa1e 100644 --- a/library/std/src/sys/hermit/net.rs +++ b/library/std/src/sys/hermit/net.rs @@ -4,7 +4,8 @@ use crate::cmp; use crate::io::{self, IoSlice, IoSliceMut}; use crate::mem; use crate::net::{Shutdown, SocketAddr}; -use crate::sys::fd::{AsFd, AsRawFd, BorrowedFd, FileDesc, FromRawFd, RawFd}; +use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, RawFd}; +use crate::sys::hermit::fd::FileDesc; use crate::sys::time::Instant; use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr}; use crate::sys_common::{AsInner, FromInner, IntoInner}; diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs index 8f927df85be..e53dbae6119 100644 --- a/library/std/src/sys/hermit/os.rs +++ b/library/std/src/sys/hermit/os.rs @@ -4,7 +4,7 @@ use crate::ffi::{CStr, OsStr, OsString}; use crate::fmt; use crate::io; use crate::marker::PhantomData; -use crate::os::unix::ffi::OsStringExt; +use crate::os::hermit::ffi::OsStringExt; use crate::path::{self, PathBuf}; use crate::str; use crate::sync::Mutex; -- cgit 1.4.1-3-g733a5