std/os/windows/io/
handle.rs

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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy