]>
Commit | Line | Data |
---|---|---|
dfeec247 | 1 | #![unstable(issue = "none", feature = "windows_stdio")] |
416331ca XL |
2 | |
3 | use crate::io; | |
60c5eb7d | 4 | use crate::mem::ManuallyDrop; |
94222f64 | 5 | use crate::os::windows::io::FromRawHandle; |
416331ca XL |
6 | use crate::sys::c; |
7 | use crate::sys::handle::Handle; | |
416331ca | 8 | |
60c5eb7d | 9 | pub struct Stdin {} |
416331ca XL |
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)?; | |
94222f64 XL |
29 | // SAFETY: The handle returned from `get_handle` must be valid and non-null. |
30 | let handle = unsafe { Handle::from_raw_handle(handle) }; | |
416331ca XL |
31 | ManuallyDrop::new(handle).write(data) |
32 | } | |
33 | ||
34 | impl Stdin { | |
3dfed10e XL |
35 | pub const fn new() -> Stdin { |
36 | Stdin {} | |
416331ca XL |
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)?; | |
94222f64 XL |
43 | // SAFETY: The handle returned from `get_handle` must be valid and non-null. |
44 | let handle = unsafe { Handle::from_raw_handle(handle) }; | |
416331ca XL |
45 | ManuallyDrop::new(handle).read(buf) |
46 | } | |
47 | } | |
48 | ||
49 | impl Stdout { | |
3dfed10e XL |
50 | pub const fn new() -> Stdout { |
51 | Stdout | |
416331ca XL |
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 { | |
3dfed10e XL |
66 | pub const fn new() -> Stderr { |
67 | Stderr | |
416331ca XL |
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> { | |
3dfed10e | 86 | Some(Stderr::new()) |
416331ca | 87 | } |