1b8a62b91Sopenharmony_ci//! The following is derived from Rust's
2b8a62b91Sopenharmony_ci//! library/std/src/os/fd/raw.rs at revision
3b8a62b91Sopenharmony_ci//! fa68e73e9947be8ffc5b3b46d899e4953a44e7e9.
4b8a62b91Sopenharmony_ci//!
5b8a62b91Sopenharmony_ci//! Raw Unix-like file descriptors.
6b8a62b91Sopenharmony_ci
7b8a62b91Sopenharmony_ci#![cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
8b8a62b91Sopenharmony_ci#![allow(unsafe_code)]
9b8a62b91Sopenharmony_ci
10b8a62b91Sopenharmony_ciuse crate::backend::c;
11b8a62b91Sopenharmony_ci
12b8a62b91Sopenharmony_ci/// Raw file descriptors.
13b8a62b91Sopenharmony_ci#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
14b8a62b91Sopenharmony_cipub type RawFd = c::c_int;
15b8a62b91Sopenharmony_ci
16b8a62b91Sopenharmony_ci/// A trait to extract the raw file descriptor from an underlying object.
17b8a62b91Sopenharmony_ci///
18b8a62b91Sopenharmony_ci/// This is only available on unix and WASI platforms and must be imported in
19b8a62b91Sopenharmony_ci/// order to call the method. Windows platforms have a corresponding
20b8a62b91Sopenharmony_ci/// `AsRawHandle` and `AsRawSocket` set of traits.
21b8a62b91Sopenharmony_ci#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
22b8a62b91Sopenharmony_cipub trait AsRawFd {
23b8a62b91Sopenharmony_ci    /// Extracts the raw file descriptor.
24b8a62b91Sopenharmony_ci    ///
25b8a62b91Sopenharmony_ci    /// This function is typically used to **borrow** an owned file descriptor.
26b8a62b91Sopenharmony_ci    /// When used in this way, this method does **not** pass ownership of the
27b8a62b91Sopenharmony_ci    /// raw file descriptor to the caller, and the file descriptor is only
28b8a62b91Sopenharmony_ci    /// guaranteed to be valid while the original object has not yet been
29b8a62b91Sopenharmony_ci    /// destroyed.
30b8a62b91Sopenharmony_ci    ///
31b8a62b91Sopenharmony_ci    /// However, borrowing is not strictly required. See [`AsFd::as_fd`]
32b8a62b91Sopenharmony_ci    /// for an API which strictly borrows a file descriptor.
33b8a62b91Sopenharmony_ci    ///
34b8a62b91Sopenharmony_ci    /// # Example
35b8a62b91Sopenharmony_ci    ///
36b8a62b91Sopenharmony_ci    /// ```no_run
37b8a62b91Sopenharmony_ci    /// use std::fs::File;
38b8a62b91Sopenharmony_ci    /// # use std::io;
39b8a62b91Sopenharmony_ci    /// #[cfg(unix)]
40b8a62b91Sopenharmony_ci    /// use std::os::unix::io::{AsRawFd, RawFd};
41b8a62b91Sopenharmony_ci    /// #[cfg(target_os = "wasi")]
42b8a62b91Sopenharmony_ci    /// use std::os::wasi::io::{AsRawFd, RawFd};
43b8a62b91Sopenharmony_ci    ///
44b8a62b91Sopenharmony_ci    /// let mut f = File::open("foo.txt")?;
45b8a62b91Sopenharmony_ci    /// // `raw_fd` is only valid as long as `f` exists.
46b8a62b91Sopenharmony_ci    /// #[cfg(any(unix, target_os = "wasi"))]
47b8a62b91Sopenharmony_ci    /// let raw_fd: RawFd = f.as_raw_fd();
48b8a62b91Sopenharmony_ci    /// # Ok::<(), io::Error>(())
49b8a62b91Sopenharmony_ci    /// ```
50b8a62b91Sopenharmony_ci    #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))]
51b8a62b91Sopenharmony_ci    fn as_raw_fd(&self) -> RawFd;
52b8a62b91Sopenharmony_ci}
53b8a62b91Sopenharmony_ci
54b8a62b91Sopenharmony_ci/// A trait to express the ability to construct an object from a raw file
55b8a62b91Sopenharmony_ci/// descriptor.
56b8a62b91Sopenharmony_ci#[cfg_attr(staged_api, stable(feature = "from_raw_os", since = "1.1.0"))]
57b8a62b91Sopenharmony_cipub trait FromRawFd {
58b8a62b91Sopenharmony_ci    /// Constructs a new instance of `Self` from the given raw file
59b8a62b91Sopenharmony_ci    /// descriptor.
60b8a62b91Sopenharmony_ci    ///
61b8a62b91Sopenharmony_ci    /// This function is typically used to **consume ownership** of the
62b8a62b91Sopenharmony_ci    /// specified file descriptor. When used in this way, the returned object
63b8a62b91Sopenharmony_ci    /// will take responsibility for closing it when the object goes out of
64b8a62b91Sopenharmony_ci    /// scope.
65b8a62b91Sopenharmony_ci    ///
66b8a62b91Sopenharmony_ci    /// However, consuming ownership is not strictly required. Use a
67b8a62b91Sopenharmony_ci    /// [`From<OwnedFd>::from`] implementation for an API which strictly
68b8a62b91Sopenharmony_ci    /// consumes ownership.
69b8a62b91Sopenharmony_ci    ///
70b8a62b91Sopenharmony_ci    /// # Safety
71b8a62b91Sopenharmony_ci    ///
72b8a62b91Sopenharmony_ci    /// The `fd` passed in must be a valid an open file descriptor.
73b8a62b91Sopenharmony_ci    ///
74b8a62b91Sopenharmony_ci    /// # Example
75b8a62b91Sopenharmony_ci    ///
76b8a62b91Sopenharmony_ci    /// ```no_run
77b8a62b91Sopenharmony_ci    /// use std::fs::File;
78b8a62b91Sopenharmony_ci    /// # use std::io;
79b8a62b91Sopenharmony_ci    /// #[cfg(unix)]
80b8a62b91Sopenharmony_ci    /// use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd};
81b8a62b91Sopenharmony_ci    /// #[cfg(target_os = "wasi")]
82b8a62b91Sopenharmony_ci    /// use std::os::wasi::io::{FromRawFd, IntoRawFd, RawFd};
83b8a62b91Sopenharmony_ci    ///
84b8a62b91Sopenharmony_ci    /// let f = File::open("foo.txt")?;
85b8a62b91Sopenharmony_ci    /// # #[cfg(any(unix, target_os = "wasi"))]
86b8a62b91Sopenharmony_ci    /// let raw_fd: RawFd = f.into_raw_fd();
87b8a62b91Sopenharmony_ci    /// // SAFETY: no other functions should call `from_raw_fd`, so there
88b8a62b91Sopenharmony_ci    /// // is only one owner for the file descriptor.
89b8a62b91Sopenharmony_ci    /// # #[cfg(any(unix, target_os = "wasi"))]
90b8a62b91Sopenharmony_ci    /// let f = unsafe { File::from_raw_fd(raw_fd) };
91b8a62b91Sopenharmony_ci    /// # Ok::<(), io::Error>(())
92b8a62b91Sopenharmony_ci    /// ```
93b8a62b91Sopenharmony_ci    #[cfg_attr(staged_api, stable(feature = "from_raw_os", since = "1.1.0"))]
94b8a62b91Sopenharmony_ci    unsafe fn from_raw_fd(fd: RawFd) -> Self;
95b8a62b91Sopenharmony_ci}
96b8a62b91Sopenharmony_ci
97b8a62b91Sopenharmony_ci/// A trait to express the ability to consume an object and acquire ownership of
98b8a62b91Sopenharmony_ci/// its raw file descriptor.
99b8a62b91Sopenharmony_ci#[cfg_attr(staged_api, stable(feature = "into_raw_os", since = "1.4.0"))]
100b8a62b91Sopenharmony_cipub trait IntoRawFd {
101b8a62b91Sopenharmony_ci    /// Consumes this object, returning the raw underlying file descriptor.
102b8a62b91Sopenharmony_ci    ///
103b8a62b91Sopenharmony_ci    /// This function is typically used to **transfer ownership** of the underlying
104b8a62b91Sopenharmony_ci    /// file descriptor to the caller. When used in this way, callers are then the unique
105b8a62b91Sopenharmony_ci    /// owners of the file descriptor and must close it once it's no longer needed.
106b8a62b91Sopenharmony_ci    ///
107b8a62b91Sopenharmony_ci    /// However, transferring ownership is not strictly required. Use a
108b8a62b91Sopenharmony_ci    /// [`Into<OwnedFd>::into`] implementation for an API which strictly
109b8a62b91Sopenharmony_ci    /// transfers ownership.
110b8a62b91Sopenharmony_ci    ///
111b8a62b91Sopenharmony_ci    /// # Example
112b8a62b91Sopenharmony_ci    ///
113b8a62b91Sopenharmony_ci    /// ```no_run
114b8a62b91Sopenharmony_ci    /// use std::fs::File;
115b8a62b91Sopenharmony_ci    /// # use std::io;
116b8a62b91Sopenharmony_ci    /// #[cfg(unix)]
117b8a62b91Sopenharmony_ci    /// use std::os::unix::io::{IntoRawFd, RawFd};
118b8a62b91Sopenharmony_ci    /// #[cfg(target_os = "wasi")]
119b8a62b91Sopenharmony_ci    /// use std::os::wasi::io::{IntoRawFd, RawFd};
120b8a62b91Sopenharmony_ci    ///
121b8a62b91Sopenharmony_ci    /// let f = File::open("foo.txt")?;
122b8a62b91Sopenharmony_ci    /// #[cfg(any(unix, target_os = "wasi"))]
123b8a62b91Sopenharmony_ci    /// let raw_fd: RawFd = f.into_raw_fd();
124b8a62b91Sopenharmony_ci    /// # Ok::<(), io::Error>(())
125b8a62b91Sopenharmony_ci    /// ```
126b8a62b91Sopenharmony_ci    #[cfg_attr(staged_api, stable(feature = "into_raw_os", since = "1.4.0"))]
127b8a62b91Sopenharmony_ci    fn into_raw_fd(self) -> RawFd;
128b8a62b91Sopenharmony_ci}
129b8a62b91Sopenharmony_ci
130b8a62b91Sopenharmony_ci#[cfg_attr(
131b8a62b91Sopenharmony_ci    staged_api,
132b8a62b91Sopenharmony_ci    stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")
133b8a62b91Sopenharmony_ci)]
134b8a62b91Sopenharmony_ciimpl AsRawFd for RawFd {
135b8a62b91Sopenharmony_ci    #[inline]
136b8a62b91Sopenharmony_ci    fn as_raw_fd(&self) -> RawFd {
137b8a62b91Sopenharmony_ci        *self
138b8a62b91Sopenharmony_ci    }
139b8a62b91Sopenharmony_ci}
140b8a62b91Sopenharmony_ci#[cfg_attr(
141b8a62b91Sopenharmony_ci    staged_api,
142b8a62b91Sopenharmony_ci    stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")
143b8a62b91Sopenharmony_ci)]
144b8a62b91Sopenharmony_ciimpl IntoRawFd for RawFd {
145b8a62b91Sopenharmony_ci    #[inline]
146b8a62b91Sopenharmony_ci    fn into_raw_fd(self) -> RawFd {
147b8a62b91Sopenharmony_ci        self
148b8a62b91Sopenharmony_ci    }
149b8a62b91Sopenharmony_ci}
150b8a62b91Sopenharmony_ci#[cfg_attr(
151b8a62b91Sopenharmony_ci    staged_api,
152b8a62b91Sopenharmony_ci    stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")
153b8a62b91Sopenharmony_ci)]
154b8a62b91Sopenharmony_ciimpl FromRawFd for RawFd {
155b8a62b91Sopenharmony_ci    #[inline]
156b8a62b91Sopenharmony_ci    unsafe fn from_raw_fd(fd: RawFd) -> RawFd {
157b8a62b91Sopenharmony_ci        fd
158b8a62b91Sopenharmony_ci    }
159b8a62b91Sopenharmony_ci}
160