#
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}