diff options
| author | Dan Gohman <dev@sunfishcode.online> | 2021-07-28 07:28:58 -0700 |
|---|---|---|
| committer | Dan Gohman <dev@sunfishcode.online> | 2021-08-19 12:02:40 -0700 |
| commit | 1dbd6d60f011dd048355ddb229bc78c366598746 (patch) | |
| tree | 77323066c61c9a24cf4f49968ed8d91dd4d2630c /library/std/src | |
| parent | 71dab738ac80c2dfadc0d83bb251c70d72d261d6 (diff) | |
| download | rust-1dbd6d60f011dd048355ddb229bc78c366598746.tar.gz rust-1dbd6d60f011dd048355ddb229bc78c366598746.zip | |
Factor out Unix and WASI fd code into a common module.
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/os/fd.rs | 292 | ||||
| -rw-r--r-- | library/std/src/os/mod.rs | 3 | ||||
| -rw-r--r-- | library/std/src/os/unix/io/fd.rs | 282 | ||||
| -rw-r--r-- | library/std/src/os/wasi/io/fd.rs | 281 |
4 files changed, 298 insertions, 560 deletions
diff --git a/library/std/src/os/fd.rs b/library/std/src/os/fd.rs new file mode 100644 index 00000000000..e5a977d9e40 --- /dev/null +++ b/library/std/src/os/fd.rs @@ -0,0 +1,292 @@ +//! Owned and borrowed Unix-like file descriptors. + +#![unstable(feature = "io_safety", issue = "87074")] +#![deny(unsafe_op_in_unsafe_fn)] + +#[cfg(unix)] +use super::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; +#[cfg(target_os = "wasi")] +use super::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; +use crate::fmt; +use crate::fs; +use crate::marker::PhantomData; +use crate::mem::forget; +use crate::os::raw; +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`. +#[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)] +#[unstable(feature = "io_safety", issue = "87074")] +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)] +#[unstable(feature = "io_safety", issue = "87074")] +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] + #[unstable(feature = "io_safety", issue = "87074")] + pub unsafe fn borrow_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, _phantom: PhantomData } } + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +impl AsRawFd for BorrowedFd<'_> { + #[inline] + fn as_raw_fd(&self) -> RawFd { + self.fd + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +impl AsRawFd for OwnedFd { + #[inline] + fn as_raw_fd(&self) -> RawFd { + self.fd + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +impl IntoRawFd for OwnedFd { + #[inline] + fn into_raw_fd(self) -> RawFd { + let fd = self.fd; + forget(self); + fd + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +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 } } + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +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 _ = libc::close(self.fd as raw::c_int); + } + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +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")] +impl fmt::Debug for OwnedFd { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("OwnedFd").field("fd", &self.fd).finish() + } +} + +/// A trait to borrow the file descriptor from an underlying object. +/// +/// 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")] +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")] + /// # use std::os::wasi::io::{AsFd, BorrowedFd}; + /// # #[cfg(unix)] + /// # use std::os::unix::io::{AsFd, BorrowedFd}; + /// + /// let mut f = File::open("foo.txt")?; + /// let borrowed_fd: BorrowedFd<'_> = f.as_fd(); + /// # Ok::<(), io::Error>(()) + /// ``` + #[unstable(feature = "io_safety", issue = "87074")] + fn as_fd(&self) -> BorrowedFd<'_>; +} + +#[unstable(feature = "io_safety", issue = "87074")] +impl AsFd for BorrowedFd<'_> { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + *self + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +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_fd(self.as_raw_fd()) } + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +impl AsFd for fs::File { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + self.as_inner().as_fd() + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +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")] +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")] +impl AsFd for crate::net::TcpStream { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + self.as_inner().socket().as_fd() + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +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")] +impl From<OwnedFd> 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, + )))) + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +impl AsFd for crate::net::TcpListener { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + self.as_inner().socket().as_fd() + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +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")] +impl From<OwnedFd> 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, + )))) + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +impl AsFd for crate::net::UdpSocket { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + self.as_inner().socket().as_fd() + } +} + +#[unstable(feature = "io_safety", issue = "87074")] +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")] +impl From<OwnedFd> 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, + )))) + } +} diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 4c9814919cd..b68936a89a5 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -121,3 +121,6 @@ mod imp { #[cfg(not(doc))] #[stable(feature = "os", since = "1.0.0")] pub use imp::*; + +#[cfg(any(unix, target_os = "wasi"))] +mod fd; diff --git a/library/std/src/os/unix/io/fd.rs b/library/std/src/os/unix/io/fd.rs index f22da625551..728b20bfb58 100644 --- a/library/std/src/os/unix/io/fd.rs +++ b/library/std/src/os/unix/io/fd.rs @@ -6,287 +6,9 @@ #[cfg(test)] mod tests; -use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; -use crate::fmt; -use crate::fs; -use crate::marker::PhantomData; -use crate::mem::forget; -use crate::os::raw; -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys_common::{AsInner, 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`. -#[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)] -#[unstable(feature = "io_safety", issue = "87074")] -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)] -#[unstable(feature = "io_safety", issue = "87074")] -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] - #[unstable(feature = "io_safety", issue = "87074")] - pub unsafe fn borrow_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, _phantom: PhantomData } } - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl AsRawFd for BorrowedFd<'_> { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.fd - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl AsRawFd for OwnedFd { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.fd - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl IntoRawFd for OwnedFd { - #[inline] - fn into_raw_fd(self) -> RawFd { - let fd = self.fd; - forget(self); - fd - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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 } } - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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 _ = libc::close(self.fd as raw::c_int); - } - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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")] -impl fmt::Debug for OwnedFd { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("OwnedFd").field("fd", &self.fd).finish() - } -} - -/// A trait to borrow the file descriptor from an underlying object. -/// -/// 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")] -pub trait AsFd { - /// Borrows the file descriptor. - /// - /// # Example - /// - /// ```rust,no_run - /// #![feature(io_safety)] - /// use std::fs::File; - /// # use std::io; - /// use std::os::unix::io::{AsFd, BorrowedFd}; - /// - /// let mut f = File::open("foo.txt")?; - /// let borrowed_fd: BorrowedFd<'_> = f.as_fd(); - /// # Ok::<(), io::Error>(()) - /// ``` - #[unstable(feature = "io_safety", issue = "87074")] - fn as_fd(&self) -> BorrowedFd<'_>; -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl AsFd for BorrowedFd<'_> { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - *self - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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_fd(self.as_raw_fd()) } - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl AsFd for fs::File { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.as_inner().as_fd() - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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")] -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")] -impl AsFd for crate::net::TcpStream { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.as_inner().socket().as_fd() - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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")] -impl From<OwnedFd> 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, - )))) - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl AsFd for crate::net::TcpListener { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.as_inner().socket().as_fd() - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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")] -impl From<OwnedFd> 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, - )))) - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl AsFd for crate::net::UdpSocket { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.as_inner().socket().as_fd() - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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")] -impl From<OwnedFd> 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, - )))) - } -} +pub use super::super::super::super::fd::*; #[unstable(feature = "io_safety", issue = "87074")] impl AsFd for crate::process::ChildStdin { diff --git a/library/std/src/os/wasi/io/fd.rs b/library/std/src/os/wasi/io/fd.rs index 8029ad68da9..e46406e5569 100644 --- a/library/std/src/os/wasi/io/fd.rs +++ b/library/std/src/os/wasi/io/fd.rs @@ -6,283 +6,4 @@ #[cfg(test)] mod tests; -use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; -use crate::fmt; -use crate::fs; -use crate::marker::PhantomData; -use crate::mem::forget; -use crate::os::raw; -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`. -#[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)] -#[unstable(feature = "io_safety", issue = "87074")] -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)] -#[unstable(feature = "io_safety", issue = "87074")] -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] - #[unstable(feature = "io_safety", issue = "87074")] - pub unsafe fn borrow_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, _phantom: PhantomData } } - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl AsRawFd for BorrowedFd<'_> { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.fd - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl AsRawFd for OwnedFd { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.fd - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl IntoRawFd for OwnedFd { - #[inline] - fn into_raw_fd(self) -> RawFd { - let fd = self.fd; - forget(self); - fd - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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 } } - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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 _ = libc::close(self.fd as raw::c_int); - } - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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")] -impl fmt::Debug for OwnedFd { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("OwnedFd").field("fd", &self.fd).finish() - } -} - -/// A trait to borrow the file descriptor from an underlying object. -/// -/// 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")] -pub trait AsFd { - /// Borrows the file descriptor. - /// - /// # Example - /// - /// ```rust,no_run - /// use std::fs::File; - /// # use std::io; - /// use std::os::wasi::io::{AsFd, BorrowedFd}; - /// - /// let mut f = File::open("foo.txt")?; - /// let borrowed_fd: BorrowedFd<'_> = f.as_fd(); - /// # Ok::<(), io::Error>(()) - /// ``` - #[unstable(feature = "io_safety", issue = "87074")] - fn as_fd(&self) -> BorrowedFd<'_>; -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl AsFd for BorrowedFd<'_> { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - *self - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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_fd(self.as_raw_fd()) } - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl AsFd for fs::File { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.as_inner().as_fd() - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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")] -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")] -impl AsFd for crate::net::TcpStream { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.as_inner().socket().as_fd() - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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")] -impl From<OwnedFd> 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, - )))) - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl AsFd for crate::net::TcpListener { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.as_inner().socket().as_fd() - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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")] -impl From<OwnedFd> 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, - )))) - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -impl AsFd for crate::net::UdpSocket { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.as_inner().socket().as_fd() - } -} - -#[unstable(feature = "io_safety", issue = "87074")] -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")] -impl From<OwnedFd> 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, - )))) - } -} +pub use super::super::super::super::fd::*; |
