]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys/windows/stdio_uwp.rs
Auto merge of #89139 - camsteffen:write-perf, r=Mark-Simulacrum
[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::sys::c;
6 use crate::sys::handle::Handle;
7
8 pub struct Stdin {}
9 pub struct Stdout;
10 pub struct Stderr;
11
12 const MAX_BUFFER_SIZE: usize = 8192;
13 pub const STDIN_BUF_SIZE: usize = MAX_BUFFER_SIZE / 2 * 3;
14
15 pub fn get_handle(handle_id: c::DWORD) -> io::Result<c::HANDLE> {
16     let handle = unsafe { c::GetStdHandle(handle_id) };
17     if handle == c::INVALID_HANDLE_VALUE {
18         Err(io::Error::last_os_error())
19     } else if handle.is_null() {
20         Err(io::Error::from_raw_os_error(c::ERROR_INVALID_HANDLE as i32))
21     } else {
22         Ok(handle)
23     }
24 }
25
26 fn write(handle_id: c::DWORD, data: &[u8]) -> io::Result<usize> {
27     let handle = get_handle(handle_id)?;
28     let handle = Handle::new(handle);
29     ManuallyDrop::new(handle).write(data)
30 }
31
32 impl Stdin {
33     pub const fn new() -> Stdin {
34         Stdin {}
35     }
36 }
37
38 impl io::Read for Stdin {
39     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
40         let handle = get_handle(c::STD_INPUT_HANDLE)?;
41         let handle = Handle::new(handle);
42         ManuallyDrop::new(handle).read(buf)
43     }
44 }
45
46 impl Stdout {
47     pub const fn new() -> Stdout {
48         Stdout
49     }
50 }
51
52 impl io::Write for Stdout {
53     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
54         write(c::STD_OUTPUT_HANDLE, buf)
55     }
56
57     fn flush(&mut self) -> io::Result<()> {
58         Ok(())
59     }
60 }
61
62 impl Stderr {
63     pub const fn new() -> Stderr {
64         Stderr
65     }
66 }
67
68 impl io::Write for Stderr {
69     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
70         write(c::STD_ERROR_HANDLE, buf)
71     }
72
73     fn flush(&mut self) -> io::Result<()> {
74         Ok(())
75     }
76 }
77
78 pub fn is_ebadf(err: &io::Error) -> bool {
79     err.raw_os_error() == Some(c::ERROR_INVALID_HANDLE as i32)
80 }
81
82 pub fn panic_output() -> Option<impl io::Write> {
83     Some(Stderr::new())
84 }