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::{AsInner, FromInner, IntoInner, cvt};
9use crate::{fmt, fs, io, ptr, sys};
10
11#[derive(Copy, Clone)]
35#[repr(transparent)]
36#[stable(feature = "io_safety", since = "1.63.0")]
37pub struct BorrowedHandle<'handle> {
38 handle: RawHandle,
39 _phantom: PhantomData<&'handle OwnedHandle>,
40}
41
42#[repr(transparent)]
64#[stable(feature = "io_safety", since = "1.63.0")]
65pub struct OwnedHandle {
66 handle: RawHandle,
67}
68
69#[repr(transparent)]
87#[stable(feature = "io_safety", since = "1.63.0")]
88#[derive(Debug)]
89pub struct HandleOrNull(RawHandle);
90
91#[repr(transparent)]
106#[stable(feature = "io_safety", since = "1.63.0")]
107#[derive(Debug)]
108pub struct HandleOrInvalid(RawHandle);
109
110#[stable(feature = "io_safety", since = "1.63.0")]
116unsafe impl Send for OwnedHandle {}
117#[stable(feature = "io_safety", since = "1.63.0")]
118unsafe impl Send for HandleOrNull {}
119#[stable(feature = "io_safety", since = "1.63.0")]
120unsafe impl Send for HandleOrInvalid {}
121#[stable(feature = "io_safety", since = "1.63.0")]
122unsafe impl Send for BorrowedHandle<'_> {}
123#[stable(feature = "io_safety", since = "1.63.0")]
124unsafe impl Sync for OwnedHandle {}
125#[stable(feature = "io_safety", since = "1.63.0")]
126unsafe impl Sync for HandleOrNull {}
127#[stable(feature = "io_safety", since = "1.63.0")]
128unsafe impl Sync for HandleOrInvalid {}
129#[stable(feature = "io_safety", since = "1.63.0")]
130unsafe impl Sync for BorrowedHandle<'_> {}
131
132impl BorrowedHandle<'_> {
133 #[inline]
148 #[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
149 #[stable(feature = "io_safety", since = "1.63.0")]
150 pub const unsafe fn borrow_raw(handle: RawHandle) -> Self {
151 Self { handle, _phantom: PhantomData }
152 }
153}
154
155#[stable(feature = "io_safety", since = "1.63.0")]
156impl TryFrom<HandleOrNull> for OwnedHandle {
157 type Error = NullHandleError;
158
159 #[inline]
160 fn try_from(handle_or_null: HandleOrNull) -> Result<Self, NullHandleError> {
161 let handle_or_null = ManuallyDrop::new(handle_or_null);
162 if handle_or_null.is_valid() {
163 Ok(unsafe { OwnedHandle::from_raw_handle(handle_or_null.0) })
165 } else {
166 Err(NullHandleError(()))
167 }
168 }
169}
170
171#[stable(feature = "io_safety", since = "1.63.0")]
172impl Drop for HandleOrNull {
173 #[inline]
174 fn drop(&mut self) {
175 if self.is_valid() {
176 unsafe {
177 let _ = sys::c::CloseHandle(self.0);
178 }
179 }
180 }
181}
182
183impl OwnedHandle {
184 #[stable(feature = "io_safety", since = "1.63.0")]
187 pub fn try_clone(&self) -> crate::io::Result<Self> {
188 self.as_handle().try_clone_to_owned()
189 }
190}
191
192impl BorrowedHandle<'_> {
193 #[stable(feature = "io_safety", since = "1.63.0")]
196 pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedHandle> {
197 self.duplicate(0, false, sys::c::DUPLICATE_SAME_ACCESS)
198 }
199
200 pub(crate) fn duplicate(
201 &self,
202 access: u32,
203 inherit: bool,
204 options: u32,
205 ) -> io::Result<OwnedHandle> {
206 let handle = self.as_raw_handle();
207
208 if handle.is_null() {
213 return unsafe { Ok(OwnedHandle::from_raw_handle(handle)) };
214 }
215
216 let mut ret = ptr::null_mut();
217 cvt(unsafe {
218 let cur_proc = sys::c::GetCurrentProcess();
219 sys::c::DuplicateHandle(
220 cur_proc,
221 handle,
222 cur_proc,
223 &mut ret,
224 access,
225 inherit as sys::c::BOOL,
226 options,
227 )
228 })?;
229 unsafe { Ok(OwnedHandle::from_raw_handle(ret)) }
230 }
231}
232
233#[stable(feature = "io_safety", since = "1.63.0")]
234impl TryFrom<HandleOrInvalid> for OwnedHandle {
235 type Error = InvalidHandleError;
236
237 #[inline]
238 fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, InvalidHandleError> {
239 let handle_or_invalid = ManuallyDrop::new(handle_or_invalid);
240 if handle_or_invalid.is_valid() {
241 Ok(unsafe { OwnedHandle::from_raw_handle(handle_or_invalid.0) })
243 } else {
244 Err(InvalidHandleError(()))
245 }
246 }
247}
248
249#[stable(feature = "io_safety", since = "1.63.0")]
250impl Drop for HandleOrInvalid {
251 #[inline]
252 fn drop(&mut self) {
253 if self.is_valid() {
254 unsafe {
255 let _ = sys::c::CloseHandle(self.0);
256 }
257 }
258 }
259}
260
261#[stable(feature = "io_safety", since = "1.63.0")]
265#[derive(Debug, Clone, PartialEq, Eq)]
266pub struct NullHandleError(());
267
268#[stable(feature = "io_safety", since = "1.63.0")]
269impl fmt::Display for NullHandleError {
270 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
271 "A HandleOrNull could not be converted to a handle because it was null".fmt(fmt)
272 }
273}
274
275#[stable(feature = "io_safety", since = "1.63.0")]
276impl crate::error::Error for NullHandleError {}
277
278#[stable(feature = "io_safety", since = "1.63.0")]
283#[derive(Debug, Clone, PartialEq, Eq)]
284pub struct InvalidHandleError(());
285
286#[stable(feature = "io_safety", since = "1.63.0")]
287impl fmt::Display for InvalidHandleError {
288 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
289 "A HandleOrInvalid could not be converted to a handle because it was INVALID_HANDLE_VALUE"
290 .fmt(fmt)
291 }
292}
293
294#[stable(feature = "io_safety", since = "1.63.0")]
295impl crate::error::Error for InvalidHandleError {}
296
297#[stable(feature = "io_safety", since = "1.63.0")]
298impl AsRawHandle for BorrowedHandle<'_> {
299 #[inline]
300 fn as_raw_handle(&self) -> RawHandle {
301 self.handle
302 }
303}
304
305#[stable(feature = "io_safety", since = "1.63.0")]
306impl AsRawHandle for OwnedHandle {
307 #[inline]
308 fn as_raw_handle(&self) -> RawHandle {
309 self.handle
310 }
311}
312
313#[stable(feature = "io_safety", since = "1.63.0")]
314impl IntoRawHandle for OwnedHandle {
315 #[inline]
316 fn into_raw_handle(self) -> RawHandle {
317 ManuallyDrop::new(self).handle
318 }
319}
320
321#[stable(feature = "io_safety", since = "1.63.0")]
322impl FromRawHandle for OwnedHandle {
323 #[inline]
324 unsafe fn from_raw_handle(handle: RawHandle) -> Self {
325 Self { handle }
326 }
327}
328
329impl HandleOrNull {
330 #[stable(feature = "io_safety", since = "1.63.0")]
345 #[inline]
346 pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
347 Self(handle)
348 }
349
350 fn is_valid(&self) -> bool {
351 !self.0.is_null()
352 }
353}
354
355impl HandleOrInvalid {
356 #[stable(feature = "io_safety", since = "1.63.0")]
372 #[inline]
373 pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
374 Self(handle)
375 }
376
377 fn is_valid(&self) -> bool {
378 self.0 != sys::c::INVALID_HANDLE_VALUE
379 }
380}
381
382#[stable(feature = "io_safety", since = "1.63.0")]
383impl Drop for OwnedHandle {
384 #[inline]
385 fn drop(&mut self) {
386 unsafe {
387 let _ = sys::c::CloseHandle(self.handle);
388 }
389 }
390}
391
392#[stable(feature = "io_safety", since = "1.63.0")]
393impl fmt::Debug for BorrowedHandle<'_> {
394 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395 f.debug_struct("BorrowedHandle").field("handle", &self.handle).finish()
396 }
397}
398
399#[stable(feature = "io_safety", since = "1.63.0")]
400impl fmt::Debug for OwnedHandle {
401 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
402 f.debug_struct("OwnedHandle").field("handle", &self.handle).finish()
403 }
404}
405
406macro_rules! impl_is_terminal {
407 ($($t:ty),*$(,)?) => {$(
408 #[unstable(feature = "sealed", issue = "none")]
409 impl crate::sealed::Sealed for $t {}
410
411 #[stable(feature = "is_terminal", since = "1.70.0")]
412 impl crate::io::IsTerminal for $t {
413 #[inline]
414 fn is_terminal(&self) -> bool {
415 crate::sys::io::is_terminal(self)
416 }
417 }
418 )*}
419}
420
421impl_is_terminal!(BorrowedHandle<'_>, OwnedHandle);
422
423#[stable(feature = "io_safety", since = "1.63.0")]
425pub trait AsHandle {
426 #[stable(feature = "io_safety", since = "1.63.0")]
440 fn as_handle(&self) -> BorrowedHandle<'_>;
441}
442
443#[stable(feature = "io_safety", since = "1.63.0")]
444impl<T: AsHandle + ?Sized> AsHandle for &T {
445 #[inline]
446 fn as_handle(&self) -> BorrowedHandle<'_> {
447 T::as_handle(self)
448 }
449}
450
451#[stable(feature = "io_safety", since = "1.63.0")]
452impl<T: AsHandle + ?Sized> AsHandle for &mut T {
453 #[inline]
454 fn as_handle(&self) -> BorrowedHandle<'_> {
455 T::as_handle(self)
456 }
457}
458
459#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
460impl<T: AsHandle + ?Sized> AsHandle for crate::sync::Arc<T> {
473 #[inline]
474 fn as_handle(&self) -> BorrowedHandle<'_> {
475 (**self).as_handle()
476 }
477}
478
479#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
480impl<T: AsHandle + ?Sized> AsHandle for crate::rc::Rc<T> {
481 #[inline]
482 fn as_handle(&self) -> BorrowedHandle<'_> {
483 (**self).as_handle()
484 }
485}
486
487#[unstable(feature = "unique_rc_arc", issue = "112566")]
488impl<T: AsHandle + ?Sized> AsHandle for crate::rc::UniqueRc<T> {
489 #[inline]
490 fn as_handle(&self) -> BorrowedHandle<'_> {
491 (**self).as_handle()
492 }
493}
494
495#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
496impl<T: AsHandle + ?Sized> AsHandle for Box<T> {
497 #[inline]
498 fn as_handle(&self) -> BorrowedHandle<'_> {
499 (**self).as_handle()
500 }
501}
502
503#[stable(feature = "io_safety", since = "1.63.0")]
504impl AsHandle for BorrowedHandle<'_> {
505 #[inline]
506 fn as_handle(&self) -> BorrowedHandle<'_> {
507 *self
508 }
509}
510
511#[stable(feature = "io_safety", since = "1.63.0")]
512impl AsHandle for OwnedHandle {
513 #[inline]
514 fn as_handle(&self) -> BorrowedHandle<'_> {
515 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
519 }
520}
521
522#[stable(feature = "io_safety", since = "1.63.0")]
523impl AsHandle for fs::File {
524 #[inline]
525 fn as_handle(&self) -> BorrowedHandle<'_> {
526 self.as_inner().as_handle()
527 }
528}
529
530#[stable(feature = "io_safety", since = "1.63.0")]
531impl From<fs::File> for OwnedHandle {
532 #[inline]
534 fn from(file: fs::File) -> OwnedHandle {
535 file.into_inner().into_inner().into_inner()
536 }
537}
538
539#[stable(feature = "io_safety", since = "1.63.0")]
540impl From<OwnedHandle> for fs::File {
541 #[inline]
543 fn from(owned: OwnedHandle) -> Self {
544 Self::from_inner(FromInner::from_inner(FromInner::from_inner(owned)))
545 }
546}
547
548#[stable(feature = "io_safety", since = "1.63.0")]
549impl AsHandle for crate::io::Stdin {
550 #[inline]
551 fn as_handle(&self) -> BorrowedHandle<'_> {
552 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
553 }
554}
555
556#[stable(feature = "io_safety", since = "1.63.0")]
557impl<'a> AsHandle for crate::io::StdinLock<'a> {
558 #[inline]
559 fn as_handle(&self) -> BorrowedHandle<'_> {
560 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
561 }
562}
563
564#[stable(feature = "io_safety", since = "1.63.0")]
565impl AsHandle for crate::io::Stdout {
566 #[inline]
567 fn as_handle(&self) -> BorrowedHandle<'_> {
568 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
569 }
570}
571
572#[stable(feature = "io_safety", since = "1.63.0")]
573impl<'a> AsHandle for crate::io::StdoutLock<'a> {
574 #[inline]
575 fn as_handle(&self) -> BorrowedHandle<'_> {
576 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
577 }
578}
579
580#[stable(feature = "io_safety", since = "1.63.0")]
581impl AsHandle for crate::io::Stderr {
582 #[inline]
583 fn as_handle(&self) -> BorrowedHandle<'_> {
584 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
585 }
586}
587
588#[stable(feature = "io_safety", since = "1.63.0")]
589impl<'a> AsHandle for crate::io::StderrLock<'a> {
590 #[inline]
591 fn as_handle(&self) -> BorrowedHandle<'_> {
592 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
593 }
594}
595
596#[stable(feature = "io_safety", since = "1.63.0")]
597impl AsHandle for crate::process::ChildStdin {
598 #[inline]
599 fn as_handle(&self) -> BorrowedHandle<'_> {
600 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
601 }
602}
603
604#[stable(feature = "io_safety", since = "1.63.0")]
605impl From<crate::process::ChildStdin> for OwnedHandle {
606 #[inline]
608 fn from(child_stdin: crate::process::ChildStdin) -> OwnedHandle {
609 unsafe { OwnedHandle::from_raw_handle(child_stdin.into_raw_handle()) }
610 }
611}
612
613#[stable(feature = "io_safety", since = "1.63.0")]
614impl AsHandle for crate::process::ChildStdout {
615 #[inline]
616 fn as_handle(&self) -> BorrowedHandle<'_> {
617 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
618 }
619}
620
621#[stable(feature = "io_safety", since = "1.63.0")]
622impl From<crate::process::ChildStdout> for OwnedHandle {
623 #[inline]
625 fn from(child_stdout: crate::process::ChildStdout) -> OwnedHandle {
626 unsafe { OwnedHandle::from_raw_handle(child_stdout.into_raw_handle()) }
627 }
628}
629
630#[stable(feature = "io_safety", since = "1.63.0")]
631impl AsHandle for crate::process::ChildStderr {
632 #[inline]
633 fn as_handle(&self) -> BorrowedHandle<'_> {
634 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
635 }
636}
637
638#[stable(feature = "io_safety", since = "1.63.0")]
639impl From<crate::process::ChildStderr> for OwnedHandle {
640 #[inline]
642 fn from(child_stderr: crate::process::ChildStderr) -> OwnedHandle {
643 unsafe { OwnedHandle::from_raw_handle(child_stderr.into_raw_handle()) }
644 }
645}
646
647#[stable(feature = "io_safety", since = "1.63.0")]
648impl<T> AsHandle for crate::thread::JoinHandle<T> {
649 #[inline]
650 fn as_handle(&self) -> BorrowedHandle<'_> {
651 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
652 }
653}
654
655#[stable(feature = "io_safety", since = "1.63.0")]
656impl<T> From<crate::thread::JoinHandle<T>> for OwnedHandle {
657 #[inline]
658 fn from(join_handle: crate::thread::JoinHandle<T>) -> OwnedHandle {
659 join_handle.into_inner().into_handle().into_inner()
660 }
661}
662
663#[stable(feature = "anonymous_pipe", since = "1.87.0")]
664impl AsHandle for io::PipeReader {
665 fn as_handle(&self) -> BorrowedHandle<'_> {
666 self.0.as_handle()
667 }
668}
669
670#[stable(feature = "anonymous_pipe", since = "1.87.0")]
671impl From<io::PipeReader> for OwnedHandle {
672 fn from(pipe: io::PipeReader) -> Self {
673 pipe.into_inner().into_inner()
674 }
675}
676
677#[stable(feature = "anonymous_pipe", since = "1.87.0")]
678impl AsHandle for io::PipeWriter {
679 fn as_handle(&self) -> BorrowedHandle<'_> {
680 self.0.as_handle()
681 }
682}
683
684#[stable(feature = "anonymous_pipe", since = "1.87.0")]
685impl From<io::PipeWriter> for OwnedHandle {
686 fn from(pipe: io::PipeWriter) -> Self {
687 pipe.into_inner().into_inner()
688 }
689}
690
691#[stable(feature = "anonymous_pipe", since = "1.87.0")]
692impl From<OwnedHandle> for io::PipeReader {
693 fn from(owned_handle: OwnedHandle) -> Self {
694 Self::from_inner(FromInner::from_inner(owned_handle))
695 }
696}
697
698#[stable(feature = "anonymous_pipe", since = "1.87.0")]
699impl From<OwnedHandle> for io::PipeWriter {
700 fn from(owned_handle: OwnedHandle) -> Self {
701 Self::from_inner(FromInner::from_inner(owned_handle))
702 }
703}