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) -> 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) -> 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 #[stable(feature = "is_terminal", since = "1.70.0")]
409 impl io::IsTerminal for $t {
410 #[inline]
411 fn is_terminal(&self) -> bool {
412 crate::sys::io::is_terminal(self)
413 }
414 }
415 )*}
416}
417
418impl_is_terminal!(BorrowedHandle<'_>, OwnedHandle);
419
420#[stable(feature = "io_safety", since = "1.63.0")]
422pub trait AsHandle {
423 #[stable(feature = "io_safety", since = "1.63.0")]
437 fn as_handle(&self) -> BorrowedHandle<'_>;
438}
439
440#[stable(feature = "io_safety", since = "1.63.0")]
441impl<T: AsHandle + ?Sized> AsHandle for &T {
442 #[inline]
443 fn as_handle(&self) -> BorrowedHandle<'_> {
444 T::as_handle(self)
445 }
446}
447
448#[stable(feature = "io_safety", since = "1.63.0")]
449impl<T: AsHandle + ?Sized> AsHandle for &mut T {
450 #[inline]
451 fn as_handle(&self) -> BorrowedHandle<'_> {
452 T::as_handle(self)
453 }
454}
455
456#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
457impl<T: AsHandle + ?Sized> AsHandle for crate::sync::Arc<T> {
470 #[inline]
471 fn as_handle(&self) -> BorrowedHandle<'_> {
472 (**self).as_handle()
473 }
474}
475
476#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
477impl<T: AsHandle + ?Sized> AsHandle for crate::rc::Rc<T> {
478 #[inline]
479 fn as_handle(&self) -> BorrowedHandle<'_> {
480 (**self).as_handle()
481 }
482}
483
484#[unstable(feature = "unique_rc_arc", issue = "112566")]
485impl<T: AsHandle + ?Sized> AsHandle for crate::rc::UniqueRc<T> {
486 #[inline]
487 fn as_handle(&self) -> BorrowedHandle<'_> {
488 (**self).as_handle()
489 }
490}
491
492#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
493impl<T: AsHandle + ?Sized> AsHandle for Box<T> {
494 #[inline]
495 fn as_handle(&self) -> BorrowedHandle<'_> {
496 (**self).as_handle()
497 }
498}
499
500#[stable(feature = "io_safety", since = "1.63.0")]
501impl AsHandle for BorrowedHandle<'_> {
502 #[inline]
503 fn as_handle(&self) -> BorrowedHandle<'_> {
504 *self
505 }
506}
507
508#[stable(feature = "io_safety", since = "1.63.0")]
509impl AsHandle for OwnedHandle {
510 #[inline]
511 fn as_handle(&self) -> BorrowedHandle<'_> {
512 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
516 }
517}
518
519#[stable(feature = "io_safety", since = "1.63.0")]
520impl AsHandle for fs::File {
521 #[inline]
522 fn as_handle(&self) -> BorrowedHandle<'_> {
523 self.as_inner().as_handle()
524 }
525}
526
527#[stable(feature = "io_safety", since = "1.63.0")]
528impl From<fs::File> for OwnedHandle {
529 #[inline]
531 fn from(file: fs::File) -> OwnedHandle {
532 file.into_inner().into_inner().into_inner()
533 }
534}
535
536#[stable(feature = "io_safety", since = "1.63.0")]
537impl From<OwnedHandle> for fs::File {
538 #[inline]
540 fn from(owned: OwnedHandle) -> Self {
541 Self::from_inner(FromInner::from_inner(FromInner::from_inner(owned)))
542 }
543}
544
545#[stable(feature = "io_safety", since = "1.63.0")]
546impl AsHandle for io::Stdin {
547 #[inline]
548 fn as_handle(&self) -> BorrowedHandle<'_> {
549 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
550 }
551}
552
553#[stable(feature = "io_safety", since = "1.63.0")]
554impl<'a> AsHandle for io::StdinLock<'a> {
555 #[inline]
556 fn as_handle(&self) -> BorrowedHandle<'_> {
557 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
558 }
559}
560
561#[stable(feature = "io_safety", since = "1.63.0")]
562impl AsHandle for io::Stdout {
563 #[inline]
564 fn as_handle(&self) -> BorrowedHandle<'_> {
565 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
566 }
567}
568
569#[stable(feature = "io_safety", since = "1.63.0")]
570impl<'a> AsHandle for io::StdoutLock<'a> {
571 #[inline]
572 fn as_handle(&self) -> BorrowedHandle<'_> {
573 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
574 }
575}
576
577#[stable(feature = "io_safety", since = "1.63.0")]
578impl AsHandle for io::Stderr {
579 #[inline]
580 fn as_handle(&self) -> BorrowedHandle<'_> {
581 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
582 }
583}
584
585#[stable(feature = "io_safety", since = "1.63.0")]
586impl<'a> AsHandle for io::StderrLock<'a> {
587 #[inline]
588 fn as_handle(&self) -> BorrowedHandle<'_> {
589 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
590 }
591}
592
593#[stable(feature = "io_safety", since = "1.63.0")]
594impl AsHandle for crate::process::ChildStdin {
595 #[inline]
596 fn as_handle(&self) -> BorrowedHandle<'_> {
597 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
598 }
599}
600
601#[stable(feature = "io_safety", since = "1.63.0")]
602impl From<crate::process::ChildStdin> for OwnedHandle {
603 #[inline]
605 fn from(child_stdin: crate::process::ChildStdin) -> OwnedHandle {
606 unsafe { OwnedHandle::from_raw_handle(child_stdin.into_raw_handle()) }
607 }
608}
609
610#[stable(feature = "io_safety", since = "1.63.0")]
611impl AsHandle for crate::process::ChildStdout {
612 #[inline]
613 fn as_handle(&self) -> BorrowedHandle<'_> {
614 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
615 }
616}
617
618#[stable(feature = "io_safety", since = "1.63.0")]
619impl From<crate::process::ChildStdout> for OwnedHandle {
620 #[inline]
622 fn from(child_stdout: crate::process::ChildStdout) -> OwnedHandle {
623 unsafe { OwnedHandle::from_raw_handle(child_stdout.into_raw_handle()) }
624 }
625}
626
627#[stable(feature = "io_safety", since = "1.63.0")]
628impl AsHandle for crate::process::ChildStderr {
629 #[inline]
630 fn as_handle(&self) -> BorrowedHandle<'_> {
631 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
632 }
633}
634
635#[stable(feature = "io_safety", since = "1.63.0")]
636impl From<crate::process::ChildStderr> for OwnedHandle {
637 #[inline]
639 fn from(child_stderr: crate::process::ChildStderr) -> OwnedHandle {
640 unsafe { OwnedHandle::from_raw_handle(child_stderr.into_raw_handle()) }
641 }
642}
643
644#[stable(feature = "io_safety", since = "1.63.0")]
645impl<T> AsHandle for crate::thread::JoinHandle<T> {
646 #[inline]
647 fn as_handle(&self) -> BorrowedHandle<'_> {
648 unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
649 }
650}
651
652#[stable(feature = "io_safety", since = "1.63.0")]
653impl<T> From<crate::thread::JoinHandle<T>> for OwnedHandle {
654 #[inline]
655 fn from(join_handle: crate::thread::JoinHandle<T>) -> OwnedHandle {
656 join_handle.into_inner().into_handle().into_inner()
657 }
658}
659
660#[stable(feature = "anonymous_pipe", since = "1.87.0")]
661impl AsHandle for io::PipeReader {
662 fn as_handle(&self) -> BorrowedHandle<'_> {
663 self.0.as_handle()
664 }
665}
666
667#[stable(feature = "anonymous_pipe", since = "1.87.0")]
668impl From<io::PipeReader> for OwnedHandle {
669 fn from(pipe: io::PipeReader) -> Self {
670 pipe.into_inner().into_inner()
671 }
672}
673
674#[stable(feature = "anonymous_pipe", since = "1.87.0")]
675impl AsHandle for io::PipeWriter {
676 fn as_handle(&self) -> BorrowedHandle<'_> {
677 self.0.as_handle()
678 }
679}
680
681#[stable(feature = "anonymous_pipe", since = "1.87.0")]
682impl From<io::PipeWriter> for OwnedHandle {
683 fn from(pipe: io::PipeWriter) -> Self {
684 pipe.into_inner().into_inner()
685 }
686}
687
688#[stable(feature = "anonymous_pipe", since = "1.87.0")]
689impl From<OwnedHandle> for io::PipeReader {
690 fn from(owned_handle: OwnedHandle) -> Self {
691 Self::from_inner(FromInner::from_inner(owned_handle))
692 }
693}
694
695#[stable(feature = "anonymous_pipe", since = "1.87.0")]
696impl From<OwnedHandle> for io::PipeWriter {
697 fn from(owned_handle: OwnedHandle) -> Self {
698 Self::from_inner(FromInner::from_inner(owned_handle))
699 }
700}