]>
Commit | Line | Data |
---|---|---|
94222f64 XL |
1 | //! Owned and borrowed OS handles. |
2 | ||
923072b8 | 3 | #![stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
4 | |
5 | use super::raw::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle}; | |
94222f64 XL |
6 | use crate::fmt; |
7 | use crate::fs; | |
5099ac24 | 8 | use crate::io; |
94222f64 XL |
9 | use crate::marker::PhantomData; |
10 | use crate::mem::forget; | |
5e7ed085 | 11 | use crate::ptr; |
94222f64 | 12 | use crate::sys::c; |
5099ac24 | 13 | use crate::sys::cvt; |
94222f64 XL |
14 | use crate::sys_common::{AsInner, FromInner, IntoInner}; |
15 | ||
16 | /// A borrowed handle. | |
17 | /// | |
18 | /// This has a lifetime parameter to tie it to the lifetime of something that | |
19 | /// owns the handle. | |
20 | /// | |
21 | /// This uses `repr(transparent)` and has the representation of a host handle, | |
22 | /// so it can be used in FFI in places where a handle is passed as an argument, | |
c295e0f8 | 23 | /// it is not captured or consumed. |
94222f64 | 24 | /// |
04454e1e FG |
25 | /// Note that it *may* have the value `-1`, which in `BorrowedHandle` always |
26 | /// represents a valid handle value, such as [the current process handle], and | |
27 | /// not `INVALID_HANDLE_VALUE`, despite the two having the same value. See | |
28 | /// [here] for the full story. | |
94222f64 | 29 | /// |
c295e0f8 XL |
30 | /// And, it *may* have the value `NULL` (0), which can occur when consoles are |
31 | /// detached from processes, or when `windows_subsystem` is used. | |
32 | /// | |
5e7ed085 FG |
33 | /// This type's `.to_owned()` implementation returns another `BorrowedHandle` |
34 | /// rather than an `OwnedHandle`. It just makes a trivial copy of the raw | |
35 | /// handle, which is then borrowed under the same lifetime. | |
36 | /// | |
94222f64 | 37 | /// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443 |
04454e1e | 38 | /// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks |
94222f64 XL |
39 | #[derive(Copy, Clone)] |
40 | #[repr(transparent)] | |
923072b8 | 41 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 | 42 | pub struct BorrowedHandle<'handle> { |
c295e0f8 | 43 | handle: RawHandle, |
94222f64 XL |
44 | _phantom: PhantomData<&'handle OwnedHandle>, |
45 | } | |
46 | ||
47 | /// An owned handle. | |
48 | /// | |
49 | /// This closes the handle on drop. | |
50 | /// | |
04454e1e FG |
51 | /// Note that it *may* have the value `-1`, which in `OwnedHandle` always |
52 | /// represents a valid handle value, such as [the current process handle], and | |
53 | /// not `INVALID_HANDLE_VALUE`, despite the two having the same value. See | |
54 | /// [here] for the full story. | |
c295e0f8 XL |
55 | /// |
56 | /// And, it *may* have the value `NULL` (0), which can occur when consoles are | |
57 | /// detached from processes, or when `windows_subsystem` is used. | |
94222f64 XL |
58 | /// |
59 | /// `OwnedHandle` uses [`CloseHandle`] to close its handle on drop. As such, | |
60 | /// it must not be used with handles to open registry keys which need to be | |
61 | /// closed with [`RegCloseKey`] instead. | |
62 | /// | |
63 | /// [`CloseHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle | |
64 | /// [`RegCloseKey`]: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regclosekey | |
65 | /// | |
66 | /// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443 | |
04454e1e | 67 | /// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks |
5e7ed085 | 68 | #[repr(transparent)] |
923072b8 | 69 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 | 70 | pub struct OwnedHandle { |
c295e0f8 | 71 | handle: RawHandle, |
94222f64 XL |
72 | } |
73 | ||
c295e0f8 XL |
74 | /// FFI type for handles in return values or out parameters, where `NULL` is used |
75 | /// as a sentry value to indicate errors, such as in the return value of `CreateThread`. This uses | |
76 | /// `repr(transparent)` and has the representation of a host handle, so that it can be used in such | |
77 | /// FFI declarations. | |
78 | /// | |
79 | /// The only thing you can usefully do with a `HandleOrNull` is to convert it into an | |
80 | /// `OwnedHandle` using its [`TryFrom`] implementation; this conversion takes care of the check for | |
81 | /// `NULL`. This ensures that such FFI calls cannot start using the handle without | |
82 | /// checking for `NULL` first. | |
83 | /// | |
04454e1e FG |
84 | /// This type may hold any handle value that [`OwnedHandle`] may hold. As with `OwnedHandle`, when |
85 | /// it holds `-1`, that value is interpreted as a valid handle value, such as | |
86 | /// [the current process handle], and not `INVALID_HANDLE_VALUE`. | |
c295e0f8 | 87 | /// |
04454e1e FG |
88 | /// If this holds a non-null handle, it will close the handle on drop. |
89 | /// | |
90 | /// [the current process handle]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess#remarks | |
c295e0f8 | 91 | #[repr(transparent)] |
923072b8 | 92 | #[stable(feature = "io_safety", since = "1.63.0")] |
c295e0f8 XL |
93 | #[derive(Debug)] |
94 | pub struct HandleOrNull(OwnedHandle); | |
95 | ||
94222f64 XL |
96 | /// FFI type for handles in return values or out parameters, where `INVALID_HANDLE_VALUE` is used |
97 | /// as a sentry value to indicate errors, such as in the return value of `CreateFileW`. This uses | |
98 | /// `repr(transparent)` and has the representation of a host handle, so that it can be used in such | |
99 | /// FFI declarations. | |
100 | /// | |
101 | /// The only thing you can usefully do with a `HandleOrInvalid` is to convert it into an | |
102 | /// `OwnedHandle` using its [`TryFrom`] implementation; this conversion takes care of the check for | |
103 | /// `INVALID_HANDLE_VALUE`. This ensures that such FFI calls cannot start using the handle without | |
104 | /// checking for `INVALID_HANDLE_VALUE` first. | |
105 | /// | |
04454e1e FG |
106 | /// This type may hold any handle value that [`OwnedHandle`] may hold, except that when it holds |
107 | /// `-1`, that value is interpreted to mean `INVALID_HANDLE_VALUE`. | |
c295e0f8 | 108 | /// |
04454e1e | 109 | /// If holds a handle other than `INVALID_HANDLE_VALUE`, it will close the handle on drop. |
94222f64 | 110 | #[repr(transparent)] |
923072b8 | 111 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 | 112 | #[derive(Debug)] |
c295e0f8 | 113 | pub struct HandleOrInvalid(OwnedHandle); |
94222f64 XL |
114 | |
115 | // The Windows [`HANDLE`] type may be transferred across and shared between | |
116 | // thread boundaries (despite containing a `*mut void`, which in general isn't | |
117 | // `Send` or `Sync`). | |
118 | // | |
119 | // [`HANDLE`]: std::os::windows::raw::HANDLE | |
923072b8 | 120 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 | 121 | unsafe impl Send for OwnedHandle {} |
923072b8 | 122 | #[stable(feature = "io_safety", since = "1.63.0")] |
c295e0f8 | 123 | unsafe impl Send for HandleOrNull {} |
923072b8 | 124 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 | 125 | unsafe impl Send for HandleOrInvalid {} |
923072b8 | 126 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 | 127 | unsafe impl Send for BorrowedHandle<'_> {} |
923072b8 | 128 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 | 129 | unsafe impl Sync for OwnedHandle {} |
923072b8 | 130 | #[stable(feature = "io_safety", since = "1.63.0")] |
c295e0f8 | 131 | unsafe impl Sync for HandleOrNull {} |
923072b8 | 132 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 | 133 | unsafe impl Sync for HandleOrInvalid {} |
923072b8 | 134 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
135 | unsafe impl Sync for BorrowedHandle<'_> {} |
136 | ||
137 | impl BorrowedHandle<'_> { | |
138 | /// Return a `BorrowedHandle` holding the given raw handle. | |
139 | /// | |
140 | /// # Safety | |
141 | /// | |
142 | /// The resource pointed to by `handle` must be a valid open handle, it | |
c295e0f8 | 143 | /// must remain open for the duration of the returned `BorrowedHandle`. |
94222f64 XL |
144 | /// |
145 | /// Note that it *may* have the value `INVALID_HANDLE_VALUE` (-1), which is | |
146 | /// sometimes a valid handle value. See [here] for the full story. | |
147 | /// | |
c295e0f8 XL |
148 | /// And, it *may* have the value `NULL` (0), which can occur when consoles are |
149 | /// detached from processes, or when `windows_subsystem` is used. | |
150 | /// | |
94222f64 XL |
151 | /// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443 |
152 | #[inline] | |
923072b8 FG |
153 | #[rustc_const_stable(feature = "io_safety", since = "1.63.0")] |
154 | #[stable(feature = "io_safety", since = "1.63.0")] | |
04454e1e | 155 | pub const unsafe fn borrow_raw(handle: RawHandle) -> Self { |
c295e0f8 XL |
156 | Self { handle, _phantom: PhantomData } |
157 | } | |
158 | } | |
159 | ||
923072b8 | 160 | #[stable(feature = "io_safety", since = "1.63.0")] |
c295e0f8 | 161 | impl TryFrom<HandleOrNull> for OwnedHandle { |
04454e1e | 162 | type Error = NullHandleError; |
c295e0f8 XL |
163 | |
164 | #[inline] | |
04454e1e | 165 | fn try_from(handle_or_null: HandleOrNull) -> Result<Self, NullHandleError> { |
c295e0f8 | 166 | let owned_handle = handle_or_null.0; |
5e7ed085 FG |
167 | if owned_handle.handle.is_null() { |
168 | // Don't call `CloseHandle`; it'd be harmless, except that it could | |
169 | // overwrite the `GetLastError` error. | |
170 | forget(owned_handle); | |
171 | ||
04454e1e | 172 | Err(NullHandleError(())) |
5e7ed085 FG |
173 | } else { |
174 | Ok(owned_handle) | |
175 | } | |
94222f64 XL |
176 | } |
177 | } | |
178 | ||
5099ac24 | 179 | impl OwnedHandle { |
923072b8 FG |
180 | /// Creates a new `OwnedHandle` instance that shares the same underlying |
181 | /// object as the existing `OwnedHandle` instance. | |
182 | #[stable(feature = "io_safety", since = "1.63.0")] | |
5099ac24 | 183 | pub fn try_clone(&self) -> crate::io::Result<Self> { |
923072b8 FG |
184 | self.as_handle().try_clone_to_owned() |
185 | } | |
186 | } | |
187 | ||
188 | impl BorrowedHandle<'_> { | |
189 | /// Creates a new `OwnedHandle` instance that shares the same underlying | |
190 | /// object as the existing `BorrowedHandle` instance. | |
191 | #[stable(feature = "io_safety", since = "1.63.0")] | |
192 | pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedHandle> { | |
5099ac24 FG |
193 | self.duplicate(0, false, c::DUPLICATE_SAME_ACCESS) |
194 | } | |
195 | ||
196 | pub(crate) fn duplicate( | |
197 | &self, | |
198 | access: c::DWORD, | |
199 | inherit: bool, | |
200 | options: c::DWORD, | |
923072b8 | 201 | ) -> io::Result<OwnedHandle> { |
5e7ed085 FG |
202 | let handle = self.as_raw_handle(); |
203 | ||
204 | // `Stdin`, `Stdout`, and `Stderr` can all hold null handles, such as | |
205 | // in a process with a detached console. `DuplicateHandle` would fail | |
206 | // if we passed it a null handle, but we can treat null as a valid | |
207 | // handle which doesn't do any I/O, and allow it to be duplicated. | |
208 | if handle.is_null() { | |
923072b8 | 209 | return unsafe { Ok(OwnedHandle::from_raw_handle(handle)) }; |
5e7ed085 FG |
210 | } |
211 | ||
212 | let mut ret = ptr::null_mut(); | |
5099ac24 FG |
213 | cvt(unsafe { |
214 | let cur_proc = c::GetCurrentProcess(); | |
215 | c::DuplicateHandle( | |
216 | cur_proc, | |
5e7ed085 | 217 | handle, |
5099ac24 FG |
218 | cur_proc, |
219 | &mut ret, | |
220 | access, | |
221 | inherit as c::BOOL, | |
222 | options, | |
223 | ) | |
224 | })?; | |
923072b8 | 225 | unsafe { Ok(OwnedHandle::from_raw_handle(ret)) } |
5099ac24 FG |
226 | } |
227 | } | |
228 | ||
923072b8 | 229 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 | 230 | impl TryFrom<HandleOrInvalid> for OwnedHandle { |
04454e1e | 231 | type Error = InvalidHandleError; |
94222f64 XL |
232 | |
233 | #[inline] | |
04454e1e | 234 | fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, InvalidHandleError> { |
c295e0f8 | 235 | let owned_handle = handle_or_invalid.0; |
5e7ed085 FG |
236 | if owned_handle.handle == c::INVALID_HANDLE_VALUE { |
237 | // Don't call `CloseHandle`; it'd be harmless, except that it could | |
238 | // overwrite the `GetLastError` error. | |
239 | forget(owned_handle); | |
240 | ||
04454e1e | 241 | Err(InvalidHandleError(())) |
5e7ed085 FG |
242 | } else { |
243 | Ok(owned_handle) | |
244 | } | |
94222f64 XL |
245 | } |
246 | } | |
247 | ||
04454e1e FG |
248 | /// This is the error type used by [`HandleOrNull`] when attempting to convert |
249 | /// into a handle, to indicate that the value is null. | |
250 | // The empty field prevents constructing this, and allows extending it in the future. | |
923072b8 | 251 | #[stable(feature = "io_safety", since = "1.63.0")] |
04454e1e FG |
252 | #[derive(Debug, Clone, PartialEq, Eq)] |
253 | pub struct NullHandleError(()); | |
254 | ||
923072b8 | 255 | #[stable(feature = "io_safety", since = "1.63.0")] |
04454e1e FG |
256 | impl fmt::Display for NullHandleError { |
257 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { | |
258 | "A HandleOrNull could not be converted to a handle because it was null".fmt(fmt) | |
259 | } | |
260 | } | |
261 | ||
923072b8 | 262 | #[stable(feature = "io_safety", since = "1.63.0")] |
04454e1e FG |
263 | impl crate::error::Error for NullHandleError {} |
264 | ||
265 | /// This is the error type used by [`HandleOrInvalid`] when attempting to | |
266 | /// convert into a handle, to indicate that the value is | |
267 | /// `INVALID_HANDLE_VALUE`. | |
268 | // The empty field prevents constructing this, and allows extending it in the future. | |
923072b8 | 269 | #[stable(feature = "io_safety", since = "1.63.0")] |
04454e1e FG |
270 | #[derive(Debug, Clone, PartialEq, Eq)] |
271 | pub struct InvalidHandleError(()); | |
272 | ||
923072b8 | 273 | #[stable(feature = "io_safety", since = "1.63.0")] |
04454e1e FG |
274 | impl fmt::Display for InvalidHandleError { |
275 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { | |
276 | "A HandleOrInvalid could not be converted to a handle because it was INVALID_HANDLE_VALUE" | |
277 | .fmt(fmt) | |
278 | } | |
279 | } | |
280 | ||
923072b8 | 281 | #[stable(feature = "io_safety", since = "1.63.0")] |
04454e1e FG |
282 | impl crate::error::Error for InvalidHandleError {} |
283 | ||
923072b8 | 284 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
285 | impl AsRawHandle for BorrowedHandle<'_> { |
286 | #[inline] | |
287 | fn as_raw_handle(&self) -> RawHandle { | |
c295e0f8 | 288 | self.handle |
94222f64 XL |
289 | } |
290 | } | |
291 | ||
923072b8 | 292 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
293 | impl AsRawHandle for OwnedHandle { |
294 | #[inline] | |
295 | fn as_raw_handle(&self) -> RawHandle { | |
c295e0f8 | 296 | self.handle |
94222f64 XL |
297 | } |
298 | } | |
299 | ||
923072b8 | 300 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
301 | impl IntoRawHandle for OwnedHandle { |
302 | #[inline] | |
303 | fn into_raw_handle(self) -> RawHandle { | |
c295e0f8 | 304 | let handle = self.handle; |
94222f64 XL |
305 | forget(self); |
306 | handle | |
307 | } | |
308 | } | |
309 | ||
923072b8 | 310 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 | 311 | impl FromRawHandle for OwnedHandle { |
94222f64 XL |
312 | #[inline] |
313 | unsafe fn from_raw_handle(handle: RawHandle) -> Self { | |
c295e0f8 XL |
314 | Self { handle } |
315 | } | |
316 | } | |
317 | ||
5e7ed085 | 318 | impl HandleOrNull { |
c295e0f8 XL |
319 | /// Constructs a new instance of `Self` from the given `RawHandle` returned |
320 | /// from a Windows API that uses null to indicate failure, such as | |
321 | /// `CreateThread`. | |
322 | /// | |
323 | /// Use `HandleOrInvalid` instead of `HandleOrNull` for APIs that | |
324 | /// use `INVALID_HANDLE_VALUE` to indicate failure. | |
325 | /// | |
326 | /// # Safety | |
327 | /// | |
5e7ed085 FG |
328 | /// The passed `handle` value must either satisfy the safety requirements |
329 | /// of [`FromRawHandle::from_raw_handle`], or be null. Note that not all | |
330 | /// Windows APIs use null for errors; see [here] for the full story. | |
c295e0f8 XL |
331 | /// |
332 | /// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443 | |
923072b8 | 333 | #[stable(feature = "io_safety", since = "1.63.0")] |
c295e0f8 | 334 | #[inline] |
5e7ed085 | 335 | pub unsafe fn from_raw_handle(handle: RawHandle) -> Self { |
c295e0f8 | 336 | Self(OwnedHandle::from_raw_handle(handle)) |
94222f64 XL |
337 | } |
338 | } | |
339 | ||
5e7ed085 | 340 | impl HandleOrInvalid { |
94222f64 XL |
341 | /// Constructs a new instance of `Self` from the given `RawHandle` returned |
342 | /// from a Windows API that uses `INVALID_HANDLE_VALUE` to indicate | |
343 | /// failure, such as `CreateFileW`. | |
344 | /// | |
c295e0f8 | 345 | /// Use `HandleOrNull` instead of `HandleOrInvalid` for APIs that |
94222f64 XL |
346 | /// use null to indicate failure. |
347 | /// | |
348 | /// # Safety | |
349 | /// | |
5e7ed085 FG |
350 | /// The passed `handle` value must either satisfy the safety requirements |
351 | /// of [`FromRawHandle::from_raw_handle`], or be | |
352 | /// `INVALID_HANDLE_VALUE` (-1). Note that not all Windows APIs use | |
353 | /// `INVALID_HANDLE_VALUE` for errors; see [here] for the full story. | |
94222f64 XL |
354 | /// |
355 | /// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443 | |
923072b8 | 356 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 | 357 | #[inline] |
5e7ed085 | 358 | pub unsafe fn from_raw_handle(handle: RawHandle) -> Self { |
c295e0f8 | 359 | Self(OwnedHandle::from_raw_handle(handle)) |
94222f64 XL |
360 | } |
361 | } | |
362 | ||
923072b8 | 363 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
364 | impl Drop for OwnedHandle { |
365 | #[inline] | |
366 | fn drop(&mut self) { | |
367 | unsafe { | |
c295e0f8 | 368 | let _ = c::CloseHandle(self.handle); |
94222f64 XL |
369 | } |
370 | } | |
371 | } | |
372 | ||
923072b8 | 373 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
374 | impl fmt::Debug for BorrowedHandle<'_> { |
375 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
376 | f.debug_struct("BorrowedHandle").field("handle", &self.handle).finish() | |
377 | } | |
378 | } | |
379 | ||
923072b8 | 380 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
381 | impl fmt::Debug for OwnedHandle { |
382 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
383 | f.debug_struct("OwnedHandle").field("handle", &self.handle).finish() | |
384 | } | |
385 | } | |
386 | ||
387 | /// A trait to borrow the handle from an underlying object. | |
923072b8 | 388 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
389 | pub trait AsHandle { |
390 | /// Borrows the handle. | |
391 | /// | |
392 | /// # Example | |
393 | /// | |
394 | /// ```rust,no_run | |
94222f64 XL |
395 | /// use std::fs::File; |
396 | /// # use std::io; | |
397 | /// use std::os::windows::io::{AsHandle, BorrowedHandle}; | |
398 | /// | |
399 | /// let mut f = File::open("foo.txt")?; | |
400 | /// let borrowed_handle: BorrowedHandle<'_> = f.as_handle(); | |
401 | /// # Ok::<(), io::Error>(()) | |
402 | /// ``` | |
923072b8 | 403 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
404 | fn as_handle(&self) -> BorrowedHandle<'_>; |
405 | } | |
406 | ||
923072b8 | 407 | #[stable(feature = "io_safety", since = "1.63.0")] |
5099ac24 FG |
408 | impl<T: AsHandle> AsHandle for &T { |
409 | #[inline] | |
410 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
411 | T::as_handle(self) | |
412 | } | |
413 | } | |
414 | ||
923072b8 | 415 | #[stable(feature = "io_safety", since = "1.63.0")] |
5099ac24 FG |
416 | impl<T: AsHandle> AsHandle for &mut T { |
417 | #[inline] | |
418 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
419 | T::as_handle(self) | |
420 | } | |
421 | } | |
422 | ||
923072b8 | 423 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
424 | impl AsHandle for BorrowedHandle<'_> { |
425 | #[inline] | |
426 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
427 | *self | |
428 | } | |
429 | } | |
430 | ||
923072b8 | 431 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
432 | impl AsHandle for OwnedHandle { |
433 | #[inline] | |
434 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
435 | // Safety: `OwnedHandle` and `BorrowedHandle` have the same validity | |
436 | // invariants, and the `BorrowdHandle` is bounded by the lifetime | |
437 | // of `&self`. | |
5e7ed085 | 438 | unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } |
94222f64 XL |
439 | } |
440 | } | |
441 | ||
923072b8 | 442 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
443 | impl AsHandle for fs::File { |
444 | #[inline] | |
445 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
446 | self.as_inner().as_handle() | |
447 | } | |
448 | } | |
449 | ||
923072b8 | 450 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
451 | impl From<fs::File> for OwnedHandle { |
452 | #[inline] | |
453 | fn from(file: fs::File) -> OwnedHandle { | |
454 | file.into_inner().into_inner().into_inner().into() | |
455 | } | |
456 | } | |
457 | ||
923072b8 | 458 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
459 | impl From<OwnedHandle> for fs::File { |
460 | #[inline] | |
461 | fn from(owned: OwnedHandle) -> Self { | |
462 | Self::from_inner(FromInner::from_inner(FromInner::from_inner(owned))) | |
463 | } | |
464 | } | |
465 | ||
923072b8 | 466 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
467 | impl AsHandle for crate::io::Stdin { |
468 | #[inline] | |
469 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
5e7ed085 | 470 | unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } |
94222f64 XL |
471 | } |
472 | } | |
473 | ||
923072b8 | 474 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
475 | impl<'a> AsHandle for crate::io::StdinLock<'a> { |
476 | #[inline] | |
477 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
5e7ed085 | 478 | unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } |
94222f64 XL |
479 | } |
480 | } | |
481 | ||
923072b8 | 482 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
483 | impl AsHandle for crate::io::Stdout { |
484 | #[inline] | |
485 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
5e7ed085 | 486 | unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } |
94222f64 XL |
487 | } |
488 | } | |
489 | ||
923072b8 | 490 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
491 | impl<'a> AsHandle for crate::io::StdoutLock<'a> { |
492 | #[inline] | |
493 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
5e7ed085 | 494 | unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } |
94222f64 XL |
495 | } |
496 | } | |
497 | ||
923072b8 | 498 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
499 | impl AsHandle for crate::io::Stderr { |
500 | #[inline] | |
501 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
5e7ed085 | 502 | unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } |
94222f64 XL |
503 | } |
504 | } | |
505 | ||
923072b8 | 506 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
507 | impl<'a> AsHandle for crate::io::StderrLock<'a> { |
508 | #[inline] | |
509 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
5e7ed085 | 510 | unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } |
94222f64 XL |
511 | } |
512 | } | |
513 | ||
923072b8 | 514 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
515 | impl AsHandle for crate::process::ChildStdin { |
516 | #[inline] | |
517 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
5e7ed085 | 518 | unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } |
94222f64 XL |
519 | } |
520 | } | |
521 | ||
923072b8 | 522 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
523 | impl From<crate::process::ChildStdin> for OwnedHandle { |
524 | #[inline] | |
525 | fn from(child_stdin: crate::process::ChildStdin) -> OwnedHandle { | |
526 | unsafe { OwnedHandle::from_raw_handle(child_stdin.into_raw_handle()) } | |
527 | } | |
528 | } | |
529 | ||
923072b8 | 530 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
531 | impl AsHandle for crate::process::ChildStdout { |
532 | #[inline] | |
533 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
5e7ed085 | 534 | unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } |
94222f64 XL |
535 | } |
536 | } | |
537 | ||
923072b8 | 538 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
539 | impl From<crate::process::ChildStdout> for OwnedHandle { |
540 | #[inline] | |
541 | fn from(child_stdout: crate::process::ChildStdout) -> OwnedHandle { | |
542 | unsafe { OwnedHandle::from_raw_handle(child_stdout.into_raw_handle()) } | |
543 | } | |
544 | } | |
545 | ||
923072b8 | 546 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
547 | impl AsHandle for crate::process::ChildStderr { |
548 | #[inline] | |
549 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
5e7ed085 | 550 | unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } |
94222f64 XL |
551 | } |
552 | } | |
553 | ||
923072b8 | 554 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
555 | impl From<crate::process::ChildStderr> for OwnedHandle { |
556 | #[inline] | |
557 | fn from(child_stderr: crate::process::ChildStderr) -> OwnedHandle { | |
558 | unsafe { OwnedHandle::from_raw_handle(child_stderr.into_raw_handle()) } | |
559 | } | |
560 | } | |
561 | ||
923072b8 | 562 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
563 | impl<T> AsHandle for crate::thread::JoinHandle<T> { |
564 | #[inline] | |
565 | fn as_handle(&self) -> BorrowedHandle<'_> { | |
5e7ed085 | 566 | unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } |
94222f64 XL |
567 | } |
568 | } | |
569 | ||
923072b8 | 570 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
571 | impl<T> From<crate::thread::JoinHandle<T>> for OwnedHandle { |
572 | #[inline] | |
573 | fn from(join_handle: crate::thread::JoinHandle<T>) -> OwnedHandle { | |
574 | join_handle.into_inner().into_handle().into_inner() | |
575 | } | |
576 | } |