1#![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#[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#[repr(transparent)]
65#[stable(feature = "io_safety", since = "1.63.0")]
66pub struct OwnedHandle {
67    handle: RawHandle,
68}
69
70#[repr(transparent)]
88#[stable(feature = "io_safety", since = "1.63.0")]
89#[derive(Debug)]
90pub struct HandleOrNull(RawHandle);
91
92#[repr(transparent)]
107#[stable(feature = "io_safety", since = "1.63.0")]
108#[derive(Debug)]
109pub struct HandleOrInvalid(RawHandle);
110
111#[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    #[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            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    #[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    #[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        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            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#[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#[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    #[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    #[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#[stable(feature = "io_safety", since = "1.63.0")]
426pub trait AsHandle {
427    #[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")]
461impl<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        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    #[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    #[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    #[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    #[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    #[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}