]>
Commit | Line | Data |
---|---|---|
416331ca XL |
1 | #![unstable(issue = "0", feature = "windows_stdio")] |
2 | ||
3 | use crate::io; | |
60c5eb7d | 4 | use crate::mem::ManuallyDrop; |
416331ca XL |
5 | use crate::sys::c; |
6 | use crate::sys::handle::Handle; | |
416331ca | 7 | |
60c5eb7d | 8 | pub struct Stdin {} |
416331ca XL |
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 fn new() -> io::Result<Stdin> { | |
60c5eb7d | 34 | Ok(Stdin {}) |
416331ca XL |
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 fn new() -> io::Result<Stdout> { | |
48 | Ok(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 fn new() -> io::Result<Stderr> { | |
64 | Ok(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 | Stderr::new().ok() | |
84 | } |