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