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