From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- library/std/src/sys/windows/stdio_uwp.rs | 87 ++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 library/std/src/sys/windows/stdio_uwp.rs (limited to 'library/std/src/sys/windows/stdio_uwp.rs') diff --git a/library/std/src/sys/windows/stdio_uwp.rs b/library/std/src/sys/windows/stdio_uwp.rs new file mode 100644 index 000000000..32550f796 --- /dev/null +++ b/library/std/src/sys/windows/stdio_uwp.rs @@ -0,0 +1,87 @@ +#![unstable(issue = "none", feature = "windows_stdio")] + +use crate::io; +use crate::mem::ManuallyDrop; +use crate::os::windows::io::FromRawHandle; +use crate::sys::c; +use crate::sys::handle::Handle; + +pub struct Stdin {} +pub struct Stdout; +pub struct Stderr; + +const MAX_BUFFER_SIZE: usize = 8192; +pub const STDIN_BUF_SIZE: usize = MAX_BUFFER_SIZE / 2 * 3; + +pub fn get_handle(handle_id: c::DWORD) -> io::Result { + let handle = unsafe { c::GetStdHandle(handle_id) }; + if handle == c::INVALID_HANDLE_VALUE { + Err(io::Error::last_os_error()) + } else if handle.is_null() { + Err(io::Error::from_raw_os_error(c::ERROR_INVALID_HANDLE as i32)) + } else { + Ok(handle) + } +} + +fn write(handle_id: c::DWORD, data: &[u8]) -> io::Result { + let handle = get_handle(handle_id)?; + // SAFETY: The handle returned from `get_handle` must be valid and non-null. + let handle = unsafe { Handle::from_raw_handle(handle) }; + ManuallyDrop::new(handle).write(data) +} + +impl Stdin { + pub const fn new() -> Stdin { + Stdin {} + } +} + +impl io::Read for Stdin { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let handle = get_handle(c::STD_INPUT_HANDLE)?; + // SAFETY: The handle returned from `get_handle` must be valid and non-null. + let handle = unsafe { Handle::from_raw_handle(handle) }; + ManuallyDrop::new(handle).read(buf) + } +} + +impl Stdout { + pub const fn new() -> Stdout { + Stdout + } +} + +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result { + write(c::STD_OUTPUT_HANDLE, buf) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Stderr { + pub const fn new() -> Stderr { + Stderr + } +} + +impl io::Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result { + write(c::STD_ERROR_HANDLE, buf) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +pub fn is_ebadf(err: &io::Error) -> bool { + err.raw_os_error() == Some(c::ERROR_INVALID_HANDLE as i32) +} + +pub fn panic_output() -> Option { + Some(Stderr::new()) +} -- cgit v1.2.3