#![stable(feature = "io_safety", since = "1.63.0")]
use super::raw::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle};
use crate::fmt;
use crate::fs;
use crate::io;
use crate::marker::PhantomData;
use crate::mem::forget;
use crate::ptr;
use crate::sys;
use crate::sys::cvt;
use crate::sys_common::{AsInner, FromInner, IntoInner};
#[derive(Copy, Clone)]
#[repr(transparent)]
#[stable(feature = "io_safety", since = "1.63.0")]
pub struct BorrowedHandle<'handle> {
handle: RawHandle,
_phantom: PhantomData<&'handle OwnedHandle>,
}
#[repr(transparent)]
#[stable(feature = "io_safety", since = "1.63.0")]
pub struct OwnedHandle {
handle: RawHandle,
}
#[repr(transparent)]
#[stable(feature = "io_safety", since = "1.63.0")]
#[derive(Debug)]
pub struct HandleOrNull(OwnedHandle);
#[repr(transparent)]
#[stable(feature = "io_safety", since = "1.63.0")]
#[derive(Debug)]
pub struct HandleOrInvalid(OwnedHandle);
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Send for OwnedHandle {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Send for HandleOrNull {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Send for HandleOrInvalid {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Send for BorrowedHandle<'_> {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Sync for OwnedHandle {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Sync for HandleOrNull {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Sync for HandleOrInvalid {}
#[stable(feature = "io_safety", since = "1.63.0")]
unsafe impl Sync for BorrowedHandle<'_> {}
impl BorrowedHandle<'_> {
#[inline]
#[rustc_const_stable(feature = "io_safety", since = "1.63.0")]
#[stable(feature = "io_safety", since = "1.63.0")]
pub const unsafe fn borrow_raw(handle: RawHandle) -> Self {
Self { handle, _phantom: PhantomData }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl TryFrom<HandleOrNull> for OwnedHandle {
type Error = NullHandleError;
#[inline]
fn try_from(handle_or_null: HandleOrNull) -> Result<Self, NullHandleError> {
let owned_handle = handle_or_null.0;
if owned_handle.handle.is_null() {
forget(owned_handle);
Err(NullHandleError(()))
} else {
Ok(owned_handle)
}
}
}
impl OwnedHandle {
#[stable(feature = "io_safety", since = "1.63.0")]
pub fn try_clone(&self) -> crate::io::Result<Self> {
self.as_handle().try_clone_to_owned()
}
}
impl BorrowedHandle<'_> {
#[stable(feature = "io_safety", since = "1.63.0")]
pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedHandle> {
self.duplicate(0, false, sys::c::DUPLICATE_SAME_ACCESS)
}
pub(crate) fn duplicate(
&self,
access: u32,
inherit: bool,
options: u32,
) -> io::Result<OwnedHandle> {
let handle = self.as_raw_handle();
if handle.is_null() {
return unsafe { Ok(OwnedHandle::from_raw_handle(handle)) };
}
let mut ret = ptr::null_mut();
cvt(unsafe {
let cur_proc = sys::c::GetCurrentProcess();
sys::c::DuplicateHandle(
cur_proc,
handle,
cur_proc,
&mut ret,
access,
inherit as sys::c::BOOL,
options,
)
})?;
unsafe { Ok(OwnedHandle::from_raw_handle(ret)) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl TryFrom<HandleOrInvalid> for OwnedHandle {
type Error = InvalidHandleError;
#[inline]
fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, InvalidHandleError> {
let owned_handle = handle_or_invalid.0;
if owned_handle.handle == sys::c::INVALID_HANDLE_VALUE {
forget(owned_handle);
Err(InvalidHandleError(()))
} else {
Ok(owned_handle)
}
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NullHandleError(());
#[stable(feature = "io_safety", since = "1.63.0")]
impl fmt::Display for NullHandleError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
"A HandleOrNull could not be converted to a handle because it was null".fmt(fmt)
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl crate::error::Error for NullHandleError {}
#[stable(feature = "io_safety", since = "1.63.0")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InvalidHandleError(());
#[stable(feature = "io_safety", since = "1.63.0")]
impl fmt::Display for InvalidHandleError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
"A HandleOrInvalid could not be converted to a handle because it was INVALID_HANDLE_VALUE"
.fmt(fmt)
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl crate::error::Error for InvalidHandleError {}
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsRawHandle for BorrowedHandle<'_> {
#[inline]
fn as_raw_handle(&self) -> RawHandle {
self.handle
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsRawHandle for OwnedHandle {
#[inline]
fn as_raw_handle(&self) -> RawHandle {
self.handle
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl IntoRawHandle for OwnedHandle {
#[inline]
fn into_raw_handle(self) -> RawHandle {
let handle = self.handle;
forget(self);
handle
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl FromRawHandle for OwnedHandle {
#[inline]
unsafe fn from_raw_handle(handle: RawHandle) -> Self {
Self { handle }
}
}
impl HandleOrNull {
#[stable(feature = "io_safety", since = "1.63.0")]
#[inline]
pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
Self(OwnedHandle::from_raw_handle(handle))
}
}
impl HandleOrInvalid {
#[stable(feature = "io_safety", since = "1.63.0")]
#[inline]
pub unsafe fn from_raw_handle(handle: RawHandle) -> Self {
Self(OwnedHandle::from_raw_handle(handle))
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl Drop for OwnedHandle {
#[inline]
fn drop(&mut self) {
unsafe {
let _ = sys::c::CloseHandle(self.handle);
}
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl fmt::Debug for BorrowedHandle<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BorrowedHandle").field("handle", &self.handle).finish()
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl fmt::Debug for OwnedHandle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OwnedHandle").field("handle", &self.handle).finish()
}
}
macro_rules! impl_is_terminal {
($($t:ty),*$(,)?) => {$(
#[unstable(feature = "sealed", issue = "none")]
impl crate::sealed::Sealed for $t {}
#[stable(feature = "is_terminal", since = "1.70.0")]
impl crate::io::IsTerminal for $t {
#[inline]
fn is_terminal(&self) -> bool {
crate::sys::io::is_terminal(self)
}
}
)*}
}
impl_is_terminal!(BorrowedHandle<'_>, OwnedHandle);
#[stable(feature = "io_safety", since = "1.63.0")]
pub trait AsHandle {
#[stable(feature = "io_safety", since = "1.63.0")]
fn as_handle(&self) -> BorrowedHandle<'_>;
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl<T: AsHandle> AsHandle for &T {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
T::as_handle(self)
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl<T: AsHandle> AsHandle for &mut T {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
T::as_handle(self)
}
}
#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
impl<T: AsHandle> AsHandle for crate::sync::Arc<T> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
(**self).as_handle()
}
}
#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
impl<T: AsHandle> AsHandle for crate::rc::Rc<T> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
(**self).as_handle()
}
}
#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
impl<T: AsHandle> AsHandle for Box<T> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
(**self).as_handle()
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for BorrowedHandle<'_> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
*self
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for OwnedHandle {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for fs::File {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
self.as_inner().as_handle()
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<fs::File> for OwnedHandle {
#[inline]
fn from(file: fs::File) -> OwnedHandle {
file.into_inner().into_inner().into_inner().into()
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedHandle> for fs::File {
#[inline]
fn from(owned: OwnedHandle) -> Self {
Self::from_inner(FromInner::from_inner(FromInner::from_inner(owned)))
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for crate::io::Stdin {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl<'a> AsHandle for crate::io::StdinLock<'a> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for crate::io::Stdout {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl<'a> AsHandle for crate::io::StdoutLock<'a> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for crate::io::Stderr {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl<'a> AsHandle for crate::io::StderrLock<'a> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for crate::process::ChildStdin {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::process::ChildStdin> for OwnedHandle {
#[inline]
fn from(child_stdin: crate::process::ChildStdin) -> OwnedHandle {
unsafe { OwnedHandle::from_raw_handle(child_stdin.into_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for crate::process::ChildStdout {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::process::ChildStdout> for OwnedHandle {
#[inline]
fn from(child_stdout: crate::process::ChildStdout) -> OwnedHandle {
unsafe { OwnedHandle::from_raw_handle(child_stdout.into_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl AsHandle for crate::process::ChildStderr {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl From<crate::process::ChildStderr> for OwnedHandle {
#[inline]
fn from(child_stderr: crate::process::ChildStderr) -> OwnedHandle {
unsafe { OwnedHandle::from_raw_handle(child_stderr.into_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl<T> AsHandle for crate::thread::JoinHandle<T> {
#[inline]
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}
#[stable(feature = "io_safety", since = "1.63.0")]
impl<T> From<crate::thread::JoinHandle<T>> for OwnedHandle {
#[inline]
fn from(join_handle: crate::thread::JoinHandle<T>) -> OwnedHandle {
join_handle.into_inner().into_handle().into_inner()
}
}