]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys/windows/stdio_uwp.rs
Rollup merge of #95211 - terrarier2111:improve-parser, r=compiler-errors
[rust.git] / library / std / src / sys / windows / stdio_uwp.rs
1 #![unstable(issue = "none", feature = "windows_stdio")]
2
3 use crate::io;
4 use crate::mem::ManuallyDrop;
5 use crate::os::windows::io::FromRawHandle;
6 use crate::sys::c;
7 use crate::sys::handle::Handle;
8
9 pub struct Stdin {}
10 pub struct Stdout;
11 pub struct Stderr;
12
13 const MAX_BUFFER_SIZE: usize = 8192;
14 pub const STDIN_BUF_SIZE: usize = MAX_BUFFER_SIZE / 2 * 3;
15
16 pub fn get_handle(handle_id: c::DWORD) -> io::Result<c::HANDLE> {
17     let handle = unsafe { c::GetStdHandle(handle_id) };
18     if handle == c::INVALID_HANDLE_VALUE {
19         Err(io::Error::last_os_error())
20     } else if handle.is_null() {
21         Err(io::Error::from_raw_os_error(c::ERROR_INVALID_HANDLE as i32))
22     } else {
23         Ok(handle)
24     }
25 }
26
27 fn write(handle_id: c::DWORD, data: &[u8]) -> io::Result<usize> {
28     let handle = get_handle(handle_id)?;
29     // SAFETY: The handle returned from `get_handle` must be valid and non-null.
30     let handle = unsafe { Handle::from_raw_handle(handle) };
31     ManuallyDrop::new(handle).write(data)
32 }
33
34 impl Stdin {
35     pub const fn new() -> Stdin {
36         Stdin {}
37     }
38 }
39
40 impl io::Read for Stdin {
41     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
42         let handle = get_handle(c::STD_INPUT_HANDLE)?;
43         // SAFETY: The handle returned from `get_handle` must be valid and non-null.
44         let handle = unsafe { Handle::from_raw_handle(handle) };
45         ManuallyDrop::new(handle).read(buf)
46     }
47 }
48
49 impl Stdout {
50     pub const fn new() -> Stdout {
51         Stdout
52     }
53 }
54
55 impl io::Write for Stdout {
56     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
57         write(c::STD_OUTPUT_HANDLE, buf)
58     }
59
60     fn flush(&mut self) -> io::Result<()> {
61         Ok(())
62     }
63 }
64
65 impl Stderr {
66     pub const fn new() -> Stderr {
67         Stderr
68     }
69 }
70
71 impl io::Write for Stderr {
72     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
73         write(c::STD_ERROR_HANDLE, buf)
74     }
75
76     fn flush(&mut self) -> io::Result<()> {
77         Ok(())
78     }
79 }
80
81 pub fn is_ebadf(err: &io::Error) -> bool {
82     err.raw_os_error() == Some(c::ERROR_INVALID_HANDLE as i32)
83 }
84
85 pub fn panic_output() -> Option<impl io::Write> {
86     Some(Stderr::new())
87 }