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