std/os/fd/
raw.rs

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