Factor out a common RawFd/AsRawFd/etc for Unix and WASI.

This commit is contained in:
Dan Gohman
2021-08-19 12:24:25 -07:00
parent 0377a63352
commit e555003e6d
16 changed files with 355 additions and 525 deletions

View File

@@ -0,0 +1,13 @@
//! Owned and borrowed Unix-like file descriptors.
#![unstable(feature = "io_safety", issue = "87074")]
#![deny(unsafe_op_in_unsafe_fn)]
// `RawFd`, `AsRawFd`, etc.
pub mod raw;
// `OwnedFd`, `AsFd`, etc.
pub mod owned;
// Implementations for `AsRawFd` etc. for network types.
mod net;

View File

@@ -1,5 +1,6 @@
use crate::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::os::fd::owned::OwnedFd;
use crate::os::fd::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
use crate::{net, sys};
macro_rules! impl_as_raw_fd {
@@ -23,7 +24,7 @@ macro_rules! impl_from_raw_fd {
unsafe fn from_raw_fd(fd: RawFd) -> net::$t {
unsafe {
let socket = sys::net::Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd)));
net::$t::from_inner(sys::net::$t::from_inner(socket))
net::$t::from_inner(sys_common::net::$t::from_inner(socket))
}
}
}

View File

@@ -3,15 +3,11 @@
#![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 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.
@@ -123,7 +119,7 @@ impl Drop for OwnedFd {
// 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);
let _ = libc::close(self.fd);
}
}
}

View File

@@ -0,0 +1,206 @@
//! Raw Unix-like file descriptors.
#![stable(feature = "rust1", since = "1.0.0")]
use crate::fs;
use crate::io;
use crate::os::raw;
#[cfg(unix)]
use crate::os::unix::io::OwnedFd;
#[cfg(target_os = "wasi")]
use crate::os::wasi::io::OwnedFd;
use crate::sys_common::{AsInner, IntoInner};
/// Raw file descriptors.
#[stable(feature = "rust1", since = "1.0.0")]
pub type RawFd = raw::c_int;
/// 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.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawFd {
/// Extracts the raw file descriptor.
///
/// This method does **not** pass ownership of the raw file descriptor
/// to the caller. The descriptor is only guaranteed to be valid while
/// the original object has not yet been destroyed.
///
/// # Example
///
/// ```no_run
/// use std::fs::File;
/// # use std::io;
/// #[cfg(unix)]
/// use std::os::unix::io::{AsRawFd, RawFd};
/// #[cfg(target_os = "wasi")]
/// use std::os::wasi::io::{AsRawFd, RawFd};
///
/// let mut f = File::open("foo.txt")?;
/// // Note that `raw_fd` is only valid as long as `f` exists.
/// 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 construct an object from a raw file
/// descriptor.
#[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 **consumes ownership** of the specified file
/// descriptor. The returned object will take responsibility for closing
/// it when the object goes out of scope.
///
/// This function is also unsafe as the primitives currently returned
/// have the contract that they are the sole owner of the file
/// descriptor they are wrapping. Usage of this function could
/// accidentally allow violating this contract which can cause memory
/// unsafety in code that relies on it being true.
///
/// # Example
///
/// ```no_run
/// use std::fs::File;
/// # use std::io;
/// #[cfg(unix)]
/// use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd};
/// #[cfg(target_os = "wasi")]
/// use std::os::wasi::io::{FromRawFd, IntoRawFd, RawFd};
///
/// let f = File::open("foo.txt")?;
/// 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.
/// 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;
}
/// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor.
#[stable(feature = "into_raw_os", since = "1.4.0")]
pub trait IntoRawFd {
/// Consumes this object, returning the raw underlying file descriptor.
///
/// This function **transfers ownership** of the underlying file descriptor
/// to the caller. Callers are then the unique owners of the file descriptor
/// and must close the descriptor once it's no longer needed.
///
/// # Example
///
/// ```no_run
/// use std::fs::File;
/// # use std::io;
/// #[cfg(unix)]
/// use std::os::unix::io::{IntoRawFd, RawFd};
/// #[cfg(target_os = "wasi")]
/// use std::os::wasi::io::{IntoRawFd, RawFd};
///
/// let f = File::open("foo.txt")?;
/// 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;
}
#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")]
impl AsRawFd for RawFd {
#[inline]
fn as_raw_fd(&self) -> RawFd {
*self
}
}
#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")]
impl IntoRawFd for RawFd {
#[inline]
fn into_raw_fd(self) -> RawFd {
self
}
}
#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")]
impl FromRawFd for RawFd {
#[inline]
unsafe fn from_raw_fd(fd: RawFd) -> RawFd {
fd
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for fs::File {
#[inline]
fn as_raw_fd(&self) -> RawFd {
self.as_inner().as_raw_fd()
}
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for fs::File {
#[inline]
unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
unsafe { fs::File::from(OwnedFd::from_raw_fd(fd)) }
}
}
#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for fs::File {
#[inline]
fn into_raw_fd(self) -> RawFd {
self.into_inner().into_inner().into_raw_fd()
}
}
#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawFd for io::Stdin {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDIN_FILENO
}
}
#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawFd for io::Stdout {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDOUT_FILENO
}
}
#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawFd for io::Stderr {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDERR_FILENO
}
}
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawFd for io::StdinLock<'a> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDIN_FILENO
}
}
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawFd for io::StdoutLock<'a> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDOUT_FILENO
}
}
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawFd for io::StderrLock<'a> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDERR_FILENO
}
}

View File

@@ -122,5 +122,5 @@ mod imp {
#[stable(feature = "os", since = "1.0.0")]
pub use imp::*;
#[cfg(any(unix, target_os = "wasi"))]
#[cfg(any(unix, target_os = "wasi", doc))]
mod fd;

View File

@@ -6,54 +6,4 @@
#[cfg(test)]
mod tests;
use crate::sys_common::{AsInner, IntoInner};
pub use super::super::super::super::fd::*;
#[unstable(feature = "io_safety", issue = "87074")]
impl AsFd for crate::process::ChildStdin {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().as_fd()
}
}
#[unstable(feature = "io_safety", issue = "87074")]
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")]
impl AsFd for crate::process::ChildStdout {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().as_fd()
}
}
#[unstable(feature = "io_safety", issue = "87074")]
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")]
impl AsFd for crate::process::ChildStderr {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().as_fd()
}
}
#[unstable(feature = "io_safety", issue = "87074")]
impl From<crate::process::ChildStderr> for OwnedFd {
#[inline]
fn from(child_stderr: crate::process::ChildStderr) -> OwnedFd {
child_stderr.into_inner().into_inner().into_inner()
}
}
pub use crate::os::fd::owned::*;

View File

@@ -2,194 +2,4 @@
#![stable(feature = "rust1", since = "1.0.0")]
use crate::fs;
use crate::io;
use crate::os::raw;
use crate::os::unix::io::OwnedFd;
use crate::sys_common::{AsInner, IntoInner};
/// Raw file descriptors.
#[stable(feature = "rust1", since = "1.0.0")]
pub type RawFd = raw::c_int;
/// A trait to extract the raw unix 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 `AsRawHandle`
/// and `AsRawSocket` set of traits.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawFd {
/// Extracts the raw file descriptor.
///
/// This method does **not** pass ownership of the raw file descriptor
/// to the caller. The descriptor is only guaranteed to be valid while
/// the original object has not yet been destroyed.
///
/// # Example
///
/// ```no_run
/// use std::fs::File;
/// # use std::io;
/// use std::os::unix::io::{AsRawFd, RawFd};
///
/// let mut f = File::open("foo.txt")?;
/// // Note that `raw_fd` is only valid as long as `f` exists.
/// 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 construct an object from a raw file
/// descriptor.
#[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 **consumes ownership** of the specified file
/// descriptor. The returned object will take responsibility for closing
/// it when the object goes out of scope.
///
/// This function is also unsafe as the primitives currently returned
/// have the contract that they are the sole owner of the file
/// descriptor they are wrapping. Usage of this function could
/// accidentally allow violating this contract which can cause memory
/// unsafety in code that relies on it being true.
///
/// # Example
///
/// ```no_run
/// use std::fs::File;
/// # use std::io;
/// use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd};
///
/// let f = File::open("foo.txt")?;
/// 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.
/// 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;
}
/// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor.
#[stable(feature = "into_raw_os", since = "1.4.0")]
pub trait IntoRawFd {
/// Consumes this object, returning the raw underlying file descriptor.
///
/// This function **transfers ownership** of the underlying file descriptor
/// to the caller. Callers are then the unique owners of the file descriptor
/// and must close the descriptor once it's no longer needed.
///
/// # Example
///
/// ```no_run
/// use std::fs::File;
/// # use std::io;
/// use std::os::unix::io::{IntoRawFd, RawFd};
///
/// let f = File::open("foo.txt")?;
/// 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;
}
#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")]
impl AsRawFd for RawFd {
#[inline]
fn as_raw_fd(&self) -> RawFd {
*self
}
}
#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")]
impl IntoRawFd for RawFd {
#[inline]
fn into_raw_fd(self) -> RawFd {
self
}
}
#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")]
impl FromRawFd for RawFd {
#[inline]
unsafe fn from_raw_fd(fd: RawFd) -> RawFd {
fd
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for fs::File {
#[inline]
fn as_raw_fd(&self) -> RawFd {
self.as_inner().as_raw_fd()
}
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for fs::File {
#[inline]
unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
fs::File::from(OwnedFd::from_raw_fd(fd))
}
}
#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for fs::File {
#[inline]
fn into_raw_fd(self) -> RawFd {
self.into_inner().into_inner().into_raw_fd()
}
}
#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawFd for io::Stdin {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDIN_FILENO
}
}
#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawFd for io::Stdout {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDOUT_FILENO
}
}
#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawFd for io::Stderr {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDERR_FILENO
}
}
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawFd for io::StdinLock<'a> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDIN_FILENO
}
}
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawFd for io::StdoutLock<'a> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDOUT_FILENO
}
}
#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawFd for io::StderrLock<'a> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDERR_FILENO
}
}
pub use crate::os::fd::raw::*;

View File

@@ -25,7 +25,6 @@ mod addr;
mod ancillary;
mod datagram;
mod listener;
mod raw_fd;
mod stream;
#[cfg(all(test, not(target_os = "emscripten")))]
mod tests;
@@ -48,7 +47,5 @@ pub use self::ancillary::*;
pub use self::datagram::*;
#[stable(feature = "unix_socket", since = "1.10.0")]
pub use self::listener::*;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::raw_fd::*;
#[stable(feature = "unix_socket", since = "1.10.0")]
pub use self::stream::*;

View File

@@ -1,43 +0,0 @@
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
use crate::{net, sys};
macro_rules! impl_as_raw_fd {
($($t:ident)*) => {$(
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::$t {
#[inline]
fn as_raw_fd(&self) -> RawFd {
self.as_inner().socket().as_raw_fd()
}
}
)*};
}
impl_as_raw_fd! { TcpStream TcpListener UdpSocket }
macro_rules! impl_from_raw_fd {
($($t:ident)*) => {$(
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for net::$t {
#[inline]
unsafe fn from_raw_fd(fd: RawFd) -> net::$t {
let socket = sys::net::Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd)));
net::$t::from_inner(sys_common::net::$t::from_inner(socket))
}
}
)*};
}
impl_from_raw_fd! { TcpStream TcpListener UdpSocket }
macro_rules! impl_into_raw_fd {
($($t:ident)*) => {$(
#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for net::$t {
#[inline]
fn into_raw_fd(self) -> RawFd {
self.into_inner().into_socket().into_inner().into_inner().into_raw_fd()
}
}
)*};
}
impl_into_raw_fd! { TcpStream TcpListener UdpSocket }

View File

@@ -4,7 +4,7 @@
use crate::ffi::OsStr;
use crate::io;
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use crate::process;
use crate::sealed::Sealed;
use crate::sys;
@@ -385,6 +385,54 @@ impl IntoRawFd for process::ChildStderr {
}
}
#[unstable(feature = "io_safety", issue = "87074")]
impl AsFd for crate::process::ChildStdin {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().as_fd()
}
}
#[unstable(feature = "io_safety", issue = "87074")]
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")]
impl AsFd for crate::process::ChildStdout {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().as_fd()
}
}
#[unstable(feature = "io_safety", issue = "87074")]
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")]
impl AsFd for crate::process::ChildStderr {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
self.as_inner().as_fd()
}
}
#[unstable(feature = "io_safety", issue = "87074")]
impl From<crate::process::ChildStderr> for OwnedFd {
#[inline]
fn from(child_stderr: crate::process::ChildStderr) -> OwnedFd {
child_stderr.into_inner().into_inner().into_inner()
}
}
/// Returns the OS-assigned process identifier associated with this process's parent.
#[stable(feature = "unix_ppid", since = "1.27.0")]
pub fn parent_id() -> u32 {

View File

@@ -6,4 +6,4 @@
#[cfg(test)]
mod tests;
pub use super::super::super::super::fd::*;
pub use crate::os::fd::owned::*;

View File

@@ -2,183 +2,4 @@
#![unstable(feature = "wasi_ext", issue = "71213")]
use crate::fs;
use crate::io;
use crate::net;
use crate::os::raw;
use crate::sys;
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::os::wasi::io::OwnedFd;
/// Raw file descriptors.
///
/// This has type `c_int` to ease compatibility with code that also compiles on
/// Unix configurations, however unlike Unix and POSIX, in WASI negative file
/// descriptors are valid. Only `-1` is reserved for indicating errors. Code
/// intending to be portable across Unix platforms and WASI should avoid
/// assuming that negative file descriptors are invalid.
pub type RawFd = raw::c_int;
/// A trait to extract the raw unix 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 `AsRawHandle`
/// and `AsRawSocket` set of traits.
pub trait AsRawFd {
/// Extracts the raw file descriptor.
///
/// This method does **not** pass ownership of the raw file descriptor
/// to the caller. The descriptor is only guaranteed to be valid while
/// the original object has not yet been destroyed.
///
/// # Example
///
/// ```no_run
/// use std::fs::File;
/// # use std::io;
/// use std::os::wasi::io::{AsRawFd, RawFd};
///
/// let mut f = File::open("foo.txt")?;
/// // Note that `raw_fd` is only valid as long as `f` exists.
/// let raw_fd: RawFd = f.as_raw_fd();
/// # Ok::<(), io::Error>(())
/// ```
fn as_raw_fd(&self) -> RawFd;
}
/// A trait to express the ability to construct an object from a raw file
/// descriptor.
pub trait FromRawFd {
/// Constructs a new instance of `Self` from the given raw file
/// descriptor.
///
/// This function **consumes ownership** of the specified file
/// descriptor. The returned object will take responsibility for closing
/// it when the object goes out of scope.
///
/// This function is also unsafe as the primitives currently returned
/// have the contract that they are the sole owner of the file
/// descriptor they are wrapping. Usage of this function could
/// accidentally allow violating this contract which can cause memory
/// unsafety in code that relies on it being true.
///
/// # Example
///
/// ```no_run
/// use std::fs::File;
/// # use std::io;
/// use std::os::wasi::io::{FromRawFd, IntoRawFd, RawFd};
///
/// let f = File::open("foo.txt")?;
/// 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.
/// let f = unsafe { File::from_raw_fd(raw_fd) };
/// # Ok::<(), io::Error>(())
/// ```
unsafe fn from_raw_fd(fd: RawFd) -> Self;
}
/// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor.
pub trait IntoRawFd {
/// Consumes this object, returning the raw underlying file descriptor.
///
/// This function **transfers ownership** of the underlying file descriptor
/// to the caller. Callers are then the unique owners of the file descriptor
/// and must close the descriptor once it's no longer needed.
///
/// # Example
///
/// ```no_run
/// use std::fs::File;
/// # use std::io;
/// use std::os::wasi::io::{IntoRawFd, RawFd};
///
/// let f = File::open("foo.txt")?;
/// let raw_fd: RawFd = f.into_raw_fd();
/// # Ok::<(), io::Error>(())
/// ```
fn into_raw_fd(self) -> RawFd;
}
impl AsRawFd for RawFd {
#[inline]
fn as_raw_fd(&self) -> RawFd {
*self
}
}
impl IntoRawFd for RawFd {
#[inline]
fn into_raw_fd(self) -> RawFd {
self
}
}
impl FromRawFd for RawFd {
#[inline]
unsafe fn from_raw_fd(fd: RawFd) -> RawFd {
fd
}
}
impl AsRawFd for fs::File {
#[inline]
fn as_raw_fd(&self) -> RawFd {
self.as_inner().as_raw_fd()
}
}
impl FromRawFd for fs::File {
#[inline]
unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
unsafe { fs::File::from(OwnedFd::from_raw_fd(fd)) }
}
}
impl IntoRawFd for fs::File {
#[inline]
fn into_raw_fd(self) -> RawFd {
self.into_inner().into_inner().into_raw_fd()
}
}
impl AsRawFd for io::Stdin {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDIN_FILENO
}
}
impl AsRawFd for io::Stdout {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDOUT_FILENO
}
}
impl AsRawFd for io::Stderr {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDERR_FILENO
}
}
impl<'a> AsRawFd for io::StdinLock<'a> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDIN_FILENO
}
}
impl<'a> AsRawFd for io::StdoutLock<'a> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDOUT_FILENO
}
}
impl<'a> AsRawFd for io::StderrLock<'a> {
#[inline]
fn as_raw_fd(&self) -> RawFd {
libc::STDERR_FILENO
}
}
pub use crate::os::fd::raw::*;

View File

@@ -1,8 +1,3 @@
//! WASI-specific networking functionality
#![unstable(feature = "wasi_ext", issue = "71213")]
mod raw_fd;
#[unstable(feature = "wasi_ext", issue = "71213")]
pub use self::raw_fd::*;

View File

@@ -3,7 +3,9 @@
#![stable(feature = "process_extensions", since = "1.2.0")]
use crate::ffi::OsStr;
use crate::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle};
use crate::os::windows::io::{
AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle,
};
use crate::process;
use crate::sealed::Sealed;
use crate::sys;
@@ -21,7 +23,7 @@ impl FromRawHandle for process::Stdio {
#[unstable(feature = "io_safety", issue = "87074")]
impl From<OwnedHandle> for process::Stdio {
fn from(handle: OwnedHandle) -> process::Stdio {
let handle = sys::handle::Handle::from_handle(handle);
let handle = sys::handle::Handle::from_inner(handle);
let io = sys::process::Stdio::Handle(handle);
process::Stdio::from_inner(io)
}
@@ -51,9 +53,9 @@ impl IntoRawHandle for process::Child {
}
#[unstable(feature = "io_safety", issue = "87074")]
impl IntoHandle for process::Child {
fn into_handle(self) -> BorrowedHandle<'_> {
self.into_inner().into_handle().into_handle()
impl From<process::Child> for OwnedHandle {
fn from(child: process::Child) -> OwnedHandle {
child.into_inner().into_handle().into_inner()
}
}

View File

@@ -5,7 +5,6 @@ use super::err2io;
use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
use crate::mem;
use crate::net::Shutdown;
use crate::os::raw::c_int;
use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
@@ -30,23 +29,25 @@ fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] {
impl WasiFd {
pub fn datasync(&self) -> io::Result<()> {
unsafe { wasi::fd_datasync(self.as_raw_fd()).map_err(err2io) }
unsafe { wasi::fd_datasync(self.as_raw_fd() as wasi::Fd).map_err(err2io) }
}
pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
unsafe { wasi::fd_pread(self.as_raw_fd(), iovec(bufs), offset).map_err(err2io) }
unsafe { wasi::fd_pread(self.as_raw_fd() as wasi::Fd, iovec(bufs), offset).map_err(err2io) }
}
pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
unsafe { wasi::fd_pwrite(self.as_raw_fd(), ciovec(bufs), offset).map_err(err2io) }
unsafe {
wasi::fd_pwrite(self.as_raw_fd() as wasi::Fd, ciovec(bufs), offset).map_err(err2io)
}
}
pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
unsafe { wasi::fd_read(self.as_raw_fd(), iovec(bufs)).map_err(err2io) }
unsafe { wasi::fd_read(self.as_raw_fd() as wasi::Fd, iovec(bufs)).map_err(err2io) }
}
pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
unsafe { wasi::fd_write(self.as_raw_fd(), ciovec(bufs)).map_err(err2io) }
unsafe { wasi::fd_write(self.as_raw_fd() as wasi::Fd, ciovec(bufs)).map_err(err2io) }
}
pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
@@ -55,37 +56,42 @@ impl WasiFd {
SeekFrom::End(pos) => (wasi::WHENCE_END, pos),
SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos),
};
unsafe { wasi::fd_seek(self.as_raw_fd(), offset, whence).map_err(err2io) }
unsafe { wasi::fd_seek(self.as_raw_fd() as wasi::Fd, offset, whence).map_err(err2io) }
}
pub fn tell(&self) -> io::Result<u64> {
unsafe { wasi::fd_tell(self.as_raw_fd()).map_err(err2io) }
unsafe { wasi::fd_tell(self.as_raw_fd() as wasi::Fd).map_err(err2io) }
}
// FIXME: __wasi_fd_fdstat_get
pub fn set_flags(&self, flags: wasi::Fdflags) -> io::Result<()> {
unsafe { wasi::fd_fdstat_set_flags(self.as_raw_fd(), flags).map_err(err2io) }
unsafe { wasi::fd_fdstat_set_flags(self.as_raw_fd() as wasi::Fd, flags).map_err(err2io) }
}
pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> {
unsafe { wasi::fd_fdstat_set_rights(self.as_raw_fd(), base, inheriting).map_err(err2io) }
unsafe {
wasi::fd_fdstat_set_rights(self.as_raw_fd() as wasi::Fd, base, inheriting)
.map_err(err2io)
}
}
pub fn sync(&self) -> io::Result<()> {
unsafe { wasi::fd_sync(self.as_raw_fd()).map_err(err2io) }
unsafe { wasi::fd_sync(self.as_raw_fd() as wasi::Fd).map_err(err2io) }
}
pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
unsafe { wasi::fd_advise(self.as_raw_fd(), offset, len, advice).map_err(err2io) }
unsafe {
wasi::fd_advise(self.as_raw_fd() as wasi::Fd, offset, len, advice).map_err(err2io)
}
}
pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> {
unsafe { wasi::fd_allocate(self.as_raw_fd(), offset, len).map_err(err2io) }
unsafe { wasi::fd_allocate(self.as_raw_fd() as wasi::Fd, offset, len).map_err(err2io) }
}
pub fn create_directory(&self, path: &str) -> io::Result<()> {
unsafe { wasi::path_create_directory(self.as_raw_fd(), path).map_err(err2io) }
unsafe { wasi::path_create_directory(self.as_raw_fd() as wasi::Fd, path).map_err(err2io) }
}
pub fn link(
@@ -96,8 +102,14 @@ impl WasiFd {
new_path: &str,
) -> io::Result<()> {
unsafe {
wasi::path_link(self.as_raw_fd(), old_flags, old_path, new_fd.as_raw_fd(), new_path)
.map_err(err2io)
wasi::path_link(
self.as_raw_fd() as wasi::Fd,
old_flags,
old_path,
new_fd.as_raw_fd() as wasi::Fd,
new_path,
)
.map_err(err2io)
}
}
@@ -112,7 +124,7 @@ impl WasiFd {
) -> io::Result<WasiFd> {
unsafe {
wasi::path_open(
self.as_raw_fd(),
self.as_raw_fd() as wasi::Fd,
dirflags,
path,
oflags,
@@ -120,32 +132,39 @@ impl WasiFd {
fs_rights_inheriting,
fs_flags,
)
.map(|fd| WasiFd::from_raw_fd(fd))
.map(|fd| WasiFd::from_raw_fd(fd as RawFd))
.map_err(err2io)
}
}
pub fn readdir(&self, buf: &mut [u8], cookie: wasi::Dircookie) -> io::Result<usize> {
unsafe {
wasi::fd_readdir(self.as_raw_fd(), buf.as_mut_ptr(), buf.len(), cookie).map_err(err2io)
wasi::fd_readdir(self.as_raw_fd() as wasi::Fd, buf.as_mut_ptr(), buf.len(), cookie)
.map_err(err2io)
}
}
pub fn readlink(&self, path: &str, buf: &mut [u8]) -> io::Result<usize> {
unsafe {
wasi::path_readlink(self.as_raw_fd(), path, buf.as_mut_ptr(), buf.len()).map_err(err2io)
wasi::path_readlink(self.as_raw_fd() as wasi::Fd, path, buf.as_mut_ptr(), buf.len())
.map_err(err2io)
}
}
pub fn rename(&self, old_path: &str, new_fd: &WasiFd, new_path: &str) -> io::Result<()> {
unsafe {
wasi::path_rename(self.as_raw_fd(), old_path, new_fd.as_raw_fd(), new_path)
.map_err(err2io)
wasi::path_rename(
self.as_raw_fd() as wasi::Fd,
old_path,
new_fd.as_raw_fd() as wasi::Fd,
new_path,
)
.map_err(err2io)
}
}
pub fn filestat_get(&self) -> io::Result<wasi::Filestat> {
unsafe { wasi::fd_filestat_get(self.as_raw_fd()).map_err(err2io) }
unsafe { wasi::fd_filestat_get(self.as_raw_fd() as wasi::Fd).map_err(err2io) }
}
pub fn filestat_set_times(
@@ -155,12 +174,13 @@ impl WasiFd {
fstflags: wasi::Fstflags,
) -> io::Result<()> {
unsafe {
wasi::fd_filestat_set_times(self.as_raw_fd(), atim, mtim, fstflags).map_err(err2io)
wasi::fd_filestat_set_times(self.as_raw_fd() as wasi::Fd, atim, mtim, fstflags)
.map_err(err2io)
}
}
pub fn filestat_set_size(&self, size: u64) -> io::Result<()> {
unsafe { wasi::fd_filestat_set_size(self.as_raw_fd(), size).map_err(err2io) }
unsafe { wasi::fd_filestat_set_size(self.as_raw_fd() as wasi::Fd, size).map_err(err2io) }
}
pub fn path_filestat_get(
@@ -168,7 +188,9 @@ impl WasiFd {
flags: wasi::Lookupflags,
path: &str,
) -> io::Result<wasi::Filestat> {
unsafe { wasi::path_filestat_get(self.as_raw_fd(), flags, path).map_err(err2io) }
unsafe {
wasi::path_filestat_get(self.as_raw_fd() as wasi::Fd, flags, path).map_err(err2io)
}
}
pub fn path_filestat_set_times(
@@ -180,21 +202,30 @@ impl WasiFd {
fstflags: wasi::Fstflags,
) -> io::Result<()> {
unsafe {
wasi::path_filestat_set_times(self.as_raw_fd(), flags, path, atim, mtim, fstflags)
.map_err(err2io)
wasi::path_filestat_set_times(
self.as_raw_fd() as wasi::Fd,
flags,
path,
atim,
mtim,
fstflags,
)
.map_err(err2io)
}
}
pub fn symlink(&self, old_path: &str, new_path: &str) -> io::Result<()> {
unsafe { wasi::path_symlink(old_path, self.as_raw_fd(), new_path).map_err(err2io) }
unsafe {
wasi::path_symlink(old_path, self.as_raw_fd() as wasi::Fd, new_path).map_err(err2io)
}
}
pub fn unlink_file(&self, path: &str) -> io::Result<()> {
unsafe { wasi::path_unlink_file(self.as_raw_fd(), path).map_err(err2io) }
unsafe { wasi::path_unlink_file(self.as_raw_fd() as wasi::Fd, path).map_err(err2io) }
}
pub fn remove_directory(&self, path: &str) -> io::Result<()> {
unsafe { wasi::path_remove_directory(self.as_raw_fd(), path).map_err(err2io) }
unsafe { wasi::path_remove_directory(self.as_raw_fd() as wasi::Fd, path).map_err(err2io) }
}
pub fn sock_recv(
@@ -202,11 +233,15 @@ impl WasiFd {
ri_data: &mut [IoSliceMut<'_>],
ri_flags: wasi::Riflags,
) -> io::Result<(usize, wasi::Roflags)> {
unsafe { wasi::sock_recv(self.as_raw_fd(), iovec(ri_data), ri_flags).map_err(err2io) }
unsafe {
wasi::sock_recv(self.as_raw_fd() as wasi::Fd, iovec(ri_data), ri_flags).map_err(err2io)
}
}
pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::Siflags) -> io::Result<usize> {
unsafe { wasi::sock_send(self.as_raw_fd(), ciovec(si_data), si_flags).map_err(err2io) }
unsafe {
wasi::sock_send(self.as_raw_fd() as wasi::Fd, ciovec(si_data), si_flags).map_err(err2io)
}
}
pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> {
@@ -215,7 +250,7 @@ impl WasiFd {
Shutdown::Write => wasi::SDFLAGS_WR,
Shutdown::Both => wasi::SDFLAGS_WR | wasi::SDFLAGS_RD,
};
unsafe { wasi::sock_shutdown(self.as_raw_fd(), how).map_err(err2io) }
unsafe { wasi::sock_shutdown(self.as_raw_fd() as wasi::Fd, how).map_err(err2io) }
}
}

View File

@@ -5,7 +5,6 @@ use crate::convert::TryFrom;
use crate::fmt;
use crate::io::{self, IoSlice, IoSliceMut};
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
use crate::os::raw::c_int;
use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
use crate::sys::unsupported;
use crate::sys_common::{AsInner, FromInner, IntoInner};