1 | //! Raw Unix-like file descriptors. |
---|---|
2 | |
3 | #![stable(feature = "rust1", since = "1.0.0")] |
4 | |
5 | #[cfg(target_os = "hermit")] |
6 | use hermit_abi as libc; |
7 | |
8 | #[cfg(not(target_os = "trusty"))] |
9 | use crate::fs; |
10 | use crate::io; |
11 | #[cfg(target_os = "hermit")] |
12 | use crate::os::hermit::io::OwnedFd; |
13 | #[cfg(not(target_os = "hermit"))] |
14 | use crate::os::raw; |
15 | #[cfg(all(doc, not(target_arch = "wasm32")))] |
16 | use crate::os::unix::io::AsFd; |
17 | #[cfg(unix)] |
18 | use crate::os::unix::io::OwnedFd; |
19 | #[cfg(target_os = "wasi")] |
20 | use crate::os::wasi::io::OwnedFd; |
21 | #[cfg(not(target_os = "trusty"))] |
22 | use crate::sys_common::{AsInner, FromInner, IntoInner}; |
23 | |
24 | /// Raw file descriptors. |
25 | #[stable(feature = "rust1", since = "1.0.0")] |
26 | #[cfg(not(target_os = "hermit"))] |
27 | pub type RawFd = raw::c_int; |
28 | #[stable(feature = "rust1", since = "1.0.0")] |
29 | #[cfg(target_os = "hermit")] |
30 | pub type RawFd = i32; |
31 | |
32 | /// A trait to extract the raw file descriptor from an underlying object. |
33 | /// |
34 | /// This is only available on unix and WASI platforms and must be imported in |
35 | /// order to call the method. Windows platforms have a corresponding |
36 | /// `AsRawHandle` and `AsRawSocket` set of traits. |
37 | #[stable(feature = "rust1", since = "1.0.0")] |
38 | pub trait AsRawFd { |
39 | /// Extracts the raw file descriptor. |
40 | /// |
41 | /// This function is typically used to **borrow** an owned file descriptor. |
42 | /// When used in this way, this method does **not** pass ownership of the |
43 | /// raw file descriptor to the caller, and the file descriptor is only |
44 | /// guaranteed to be valid while the original object has not yet been |
45 | /// destroyed. |
46 | /// |
47 | /// However, borrowing is not strictly required. See [`AsFd::as_fd`] |
48 | /// for an API which strictly borrows a file descriptor. |
49 | /// |
50 | /// # Example |
51 | /// |
52 | /// ```no_run |
53 | /// use std::fs::File; |
54 | /// # use std::io; |
55 | /// #[cfg(any(unix, target_os = "wasi"))] |
56 | /// use std::os::fd::{AsRawFd, RawFd}; |
57 | /// |
58 | /// let mut f = File::open("foo.txt")?; |
59 | /// // Note that `raw_fd` is only valid as long as `f` exists. |
60 | /// #[cfg(any(unix, target_os = "wasi"))] |
61 | /// let raw_fd: RawFd = f.as_raw_fd(); |
62 | /// # Ok::<(), io::Error>(()) |
63 | /// ``` |
64 | #[stable(feature = "rust1", since = "1.0.0")] |
65 | fn as_raw_fd(&self) -> RawFd; |
66 | } |
67 | |
68 | /// A trait to express the ability to construct an object from a raw file |
69 | /// descriptor. |
70 | #[stable(feature = "from_raw_os", since = "1.1.0")] |
71 | pub trait FromRawFd { |
72 | /// Constructs a new instance of `Self` from the given raw file |
73 | /// descriptor. |
74 | /// |
75 | /// This function is typically used to **consume ownership** of the |
76 | /// specified file descriptor. When used in this way, the returned object |
77 | /// will take responsibility for closing it when the object goes out of |
78 | /// scope. |
79 | /// |
80 | /// However, consuming ownership is not strictly required. Use a |
81 | /// [`From<OwnedFd>::from`] implementation for an API which strictly |
82 | /// consumes ownership. |
83 | /// |
84 | /// # Safety |
85 | /// |
86 | /// The `fd` passed in must be an [owned file descriptor][io-safety]; |
87 | /// in particular, it must be open. |
88 | /// |
89 | /// [io-safety]: io#io-safety |
90 | /// |
91 | /// # Example |
92 | /// |
93 | /// ```no_run |
94 | /// use std::fs::File; |
95 | /// # use std::io; |
96 | /// #[cfg(any(unix, target_os = "wasi"))] |
97 | /// use std::os::fd::{FromRawFd, IntoRawFd, RawFd}; |
98 | /// |
99 | /// let f = File::open("foo.txt")?; |
100 | /// # #[cfg(any(unix, target_os = "wasi"))] |
101 | /// let raw_fd: RawFd = f.into_raw_fd(); |
102 | /// // SAFETY: no other functions should call `from_raw_fd`, so there |
103 | /// // is only one owner for the file descriptor. |
104 | /// # #[cfg(any(unix, target_os = "wasi"))] |
105 | /// let f = unsafe { File::from_raw_fd(raw_fd) }; |
106 | /// # Ok::<(), io::Error>(()) |
107 | /// ``` |
108 | #[stable(feature = "from_raw_os", since = "1.1.0")] |
109 | unsafe fn from_raw_fd(fd: RawFd) -> Self; |
110 | } |
111 | |
112 | /// A trait to express the ability to consume an object and acquire ownership of |
113 | /// its raw file descriptor. |
114 | #[stable(feature = "into_raw_os", since = "1.4.0")] |
115 | pub trait IntoRawFd { |
116 | /// Consumes this object, returning the raw underlying file descriptor. |
117 | /// |
118 | /// This function is typically used to **transfer ownership** of the underlying |
119 | /// file descriptor to the caller. When used in this way, callers are then the unique |
120 | /// owners of the file descriptor and must close it once it's no longer needed. |
121 | /// |
122 | /// However, transferring ownership is not strictly required. Use a |
123 | /// [`Into<OwnedFd>::into`] implementation for an API which strictly |
124 | /// transfers ownership. |
125 | /// |
126 | /// # Example |
127 | /// |
128 | /// ```no_run |
129 | /// use std::fs::File; |
130 | /// # use std::io; |
131 | /// #[cfg(any(unix, target_os = "wasi"))] |
132 | /// use std::os::fd::{IntoRawFd, RawFd}; |
133 | /// |
134 | /// let f = File::open("foo.txt")?; |
135 | /// #[cfg(any(unix, target_os = "wasi"))] |
136 | /// let raw_fd: RawFd = f.into_raw_fd(); |
137 | /// # Ok::<(), io::Error>(()) |
138 | /// ``` |
139 | #[must_use= "losing the raw file descriptor may leak resources"] |
140 | #[stable(feature = "into_raw_os", since = "1.4.0")] |
141 | fn into_raw_fd(self) -> RawFd; |
142 | } |
143 | |
144 | #[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")] |
145 | impl AsRawFd for RawFd { |
146 | #[inline] |
147 | fn as_raw_fd(&self) -> RawFd { |
148 | *self |
149 | } |
150 | } |
151 | #[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")] |
152 | impl IntoRawFd for RawFd { |
153 | #[inline] |
154 | fn into_raw_fd(self) -> RawFd { |
155 | self |
156 | } |
157 | } |
158 | #[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")] |
159 | impl FromRawFd for RawFd { |
160 | #[inline] |
161 | unsafe fn from_raw_fd(fd: RawFd) -> RawFd { |
162 | fd |
163 | } |
164 | } |
165 | |
166 | #[stable(feature = "rust1", since = "1.0.0")] |
167 | #[cfg(not(target_os = "trusty"))] |
168 | impl AsRawFd for fs::File { |
169 | #[inline] |
170 | fn as_raw_fd(&self) -> RawFd { |
171 | self.as_inner().as_raw_fd() |
172 | } |
173 | } |
174 | #[stable(feature = "from_raw_os", since = "1.1.0")] |
175 | #[cfg(not(target_os = "trusty"))] |
176 | impl FromRawFd for fs::File { |
177 | #[inline] |
178 | unsafe fn from_raw_fd(fd: RawFd) -> fs::File { |
179 | unsafe { fs::File::from(OwnedFd::from_raw_fd(fd)) } |
180 | } |
181 | } |
182 | #[stable(feature = "into_raw_os", since = "1.4.0")] |
183 | #[cfg(not(target_os = "trusty"))] |
184 | impl IntoRawFd for fs::File { |
185 | #[inline] |
186 | fn into_raw_fd(self) -> RawFd { |
187 | self.into_inner().into_inner().into_raw_fd() |
188 | } |
189 | } |
190 | |
191 | #[stable(feature = "asraw_stdio", since = "1.21.0")] |
192 | #[cfg(not(target_os = "trusty"))] |
193 | impl AsRawFd for io::Stdin { |
194 | #[inline] |
195 | fn as_raw_fd(&self) -> RawFd { |
196 | libc::STDIN_FILENO |
197 | } |
198 | } |
199 | |
200 | #[stable(feature = "asraw_stdio", since = "1.21.0")] |
201 | impl AsRawFd for io::Stdout { |
202 | #[inline] |
203 | fn as_raw_fd(&self) -> RawFd { |
204 | libc::STDOUT_FILENO |
205 | } |
206 | } |
207 | |
208 | #[stable(feature = "asraw_stdio", since = "1.21.0")] |
209 | impl AsRawFd for io::Stderr { |
210 | #[inline] |
211 | fn as_raw_fd(&self) -> RawFd { |
212 | libc::STDERR_FILENO |
213 | } |
214 | } |
215 | |
216 | #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] |
217 | #[cfg(not(target_os = "trusty"))] |
218 | impl<'a> AsRawFd for io::StdinLock<'a> { |
219 | #[inline] |
220 | fn as_raw_fd(&self) -> RawFd { |
221 | libc::STDIN_FILENO |
222 | } |
223 | } |
224 | |
225 | #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] |
226 | impl<'a> AsRawFd for io::StdoutLock<'a> { |
227 | #[inline] |
228 | fn as_raw_fd(&self) -> RawFd { |
229 | libc::STDOUT_FILENO |
230 | } |
231 | } |
232 | |
233 | #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] |
234 | impl<'a> AsRawFd for io::StderrLock<'a> { |
235 | #[inline] |
236 | fn as_raw_fd(&self) -> RawFd { |
237 | libc::STDERR_FILENO |
238 | } |
239 | } |
240 | |
241 | /// This impl allows implementing traits that require `AsRawFd` on Arc. |
242 | /// ``` |
243 | /// # #[cfg(any(unix, target_os = "wasi"))] mod group_cfg { |
244 | /// # #[cfg(target_os = "wasi")] |
245 | /// # use std::os::wasi::io::AsRawFd; |
246 | /// # #[cfg(unix)] |
247 | /// # use std::os::unix::io::AsRawFd; |
248 | /// use std::net::UdpSocket; |
249 | /// use std::sync::Arc; |
250 | /// trait MyTrait: AsRawFd { |
251 | /// } |
252 | /// impl MyTrait for Arc<UdpSocket> {} |
253 | /// impl MyTrait for Box<UdpSocket> {} |
254 | /// # } |
255 | /// ``` |
256 | #[stable(feature = "asrawfd_ptrs", since = "1.63.0")] |
257 | impl<T: AsRawFd> AsRawFd for crate::sync::Arc<T> { |
258 | #[inline] |
259 | fn as_raw_fd(&self) -> RawFd { |
260 | (**self).as_raw_fd() |
261 | } |
262 | } |
263 | |
264 | #[stable(feature = "asfd_rc", since = "1.69.0")] |
265 | impl<T: AsRawFd> AsRawFd for crate::rc::Rc<T> { |
266 | #[inline] |
267 | fn as_raw_fd(&self) -> RawFd { |
268 | (**self).as_raw_fd() |
269 | } |
270 | } |
271 | |
272 | #[unstable(feature = "unique_rc_arc", issue = "112566")] |
273 | impl<T: AsRawFd + ?Sized> AsRawFd for crate::rc::UniqueRc<T> { |
274 | #[inline] |
275 | fn as_raw_fd(&self) -> RawFd { |
276 | (**self).as_raw_fd() |
277 | } |
278 | } |
279 | |
280 | #[stable(feature = "asrawfd_ptrs", since = "1.63.0")] |
281 | impl<T: AsRawFd> AsRawFd for Box<T> { |
282 | #[inline] |
283 | fn as_raw_fd(&self) -> RawFd { |
284 | (**self).as_raw_fd() |
285 | } |
286 | } |
287 | |
288 | #[stable(feature = "anonymous_pipe", since = "1.87.0")] |
289 | #[cfg(not(target_os = "trusty"))] |
290 | impl AsRawFd for io::PipeReader { |
291 | fn as_raw_fd(&self) -> RawFd { |
292 | self.0.as_raw_fd() |
293 | } |
294 | } |
295 | |
296 | #[stable(feature = "anonymous_pipe", since = "1.87.0")] |
297 | #[cfg(not(target_os = "trusty"))] |
298 | impl FromRawFd for io::PipeReader { |
299 | unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { |
300 | Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) }) |
301 | } |
302 | } |
303 | |
304 | #[stable(feature = "anonymous_pipe", since = "1.87.0")] |
305 | #[cfg(not(target_os = "trusty"))] |
306 | impl IntoRawFd for io::PipeReader { |
307 | fn into_raw_fd(self) -> RawFd { |
308 | self.0.into_raw_fd() |
309 | } |
310 | } |
311 | |
312 | #[stable(feature = "anonymous_pipe", since = "1.87.0")] |
313 | #[cfg(not(target_os = "trusty"))] |
314 | impl AsRawFd for io::PipeWriter { |
315 | fn as_raw_fd(&self) -> RawFd { |
316 | self.0.as_raw_fd() |
317 | } |
318 | } |
319 | |
320 | #[stable(feature = "anonymous_pipe", since = "1.87.0")] |
321 | #[cfg(not(target_os = "trusty"))] |
322 | impl FromRawFd for io::PipeWriter { |
323 | unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { |
324 | Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) }) |
325 | } |
326 | } |
327 | |
328 | #[stable(feature = "anonymous_pipe", since = "1.87.0")] |
329 | #[cfg(not(target_os = "trusty"))] |
330 | impl IntoRawFd for io::PipeWriter { |
331 | fn into_raw_fd(self) -> RawFd { |
332 | self.0.into_raw_fd() |
333 | } |
334 | } |
335 |
Definitions
Learn Rust with the experts
Find out more