Skip to content

Commit a7ad699

Browse files
committed
std: win: Don't use console APIs on UWP
1 parent 07d11ae commit a7ad699

File tree

3 files changed

+119
-26
lines changed

3 files changed

+119
-26
lines changed

src/libstd/sys/windows/c.rs

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ pub type ULONG = c_ulong;
3939
pub type LPBOOL = *mut BOOL;
4040
pub type LPBYTE = *mut BYTE;
4141
pub type LPCSTR = *const CHAR;
42-
pub type LPCVOID = *const c_void;
4342
pub type LPCWSTR = *const WCHAR;
4443
pub type LPDWORD = *mut DWORD;
4544
pub type LPHANDLE = *mut HANDLE;
@@ -613,16 +612,6 @@ pub enum EXCEPTION_DISPOSITION {
613612
ExceptionCollidedUnwind
614613
}
615614

616-
#[repr(C)]
617-
#[derive(Copy, Clone)]
618-
pub struct CONSOLE_READCONSOLE_CONTROL {
619-
pub nLength: ULONG,
620-
pub nInitialChars: ULONG,
621-
pub dwCtrlWakeupMask: ULONG,
622-
pub dwControlKeyState: ULONG,
623-
}
624-
pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL;
625-
626615
#[repr(C)]
627616
#[derive(Copy)]
628617
pub struct fd_set {
@@ -646,6 +635,17 @@ pub struct timeval {
646635
// Functions forbidden when targeting UWP
647636
#[cfg(not(target_vendor = "uwp"))]
648637
ifdef! {
638+
#[repr(C)]
639+
#[derive(Copy, Clone)]
640+
pub struct CONSOLE_READCONSOLE_CONTROL {
641+
pub nLength: ULONG,
642+
pub nInitialChars: ULONG,
643+
pub dwCtrlWakeupMask: ULONG,
644+
pub dwControlKeyState: ULONG,
645+
}
646+
647+
pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL;
648+
649649
#[repr(C)]
650650
pub struct BY_HANDLE_FILE_INFORMATION {
651651
pub dwFileAttributes: DWORD,
@@ -661,6 +661,7 @@ ifdef! {
661661
}
662662

663663
pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
664+
pub type LPCVOID = *const c_void;
664665

665666
pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
666667

@@ -670,6 +671,20 @@ ifdef! {
670671
#[link_name = "SystemFunction036"]
671672
pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN;
672673

674+
pub fn ReadConsoleW(hConsoleInput: HANDLE,
675+
lpBuffer: LPVOID,
676+
nNumberOfCharsToRead: DWORD,
677+
lpNumberOfCharsRead: LPDWORD,
678+
pInputControl: PCONSOLE_READCONSOLE_CONTROL) -> BOOL;
679+
680+
pub fn WriteConsoleW(hConsoleOutput: HANDLE,
681+
lpBuffer: LPCVOID,
682+
nNumberOfCharsToWrite: DWORD,
683+
lpNumberOfCharsWritten: LPDWORD,
684+
lpReserved: LPVOID) -> BOOL;
685+
686+
pub fn GetConsoleMode(hConsoleHandle: HANDLE,
687+
lpMode: LPDWORD) -> BOOL;
673688
// Allowed but unused by UWP
674689
pub fn OpenProcessToken(ProcessHandle: HANDLE,
675690
DesiredAccess: DWORD,
@@ -754,20 +769,6 @@ extern "system" {
754769
pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
755770
pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
756771

757-
pub fn ReadConsoleW(hConsoleInput: HANDLE,
758-
lpBuffer: LPVOID,
759-
nNumberOfCharsToRead: DWORD,
760-
lpNumberOfCharsRead: LPDWORD,
761-
pInputControl: PCONSOLE_READCONSOLE_CONTROL) -> BOOL;
762-
763-
pub fn WriteConsoleW(hConsoleOutput: HANDLE,
764-
lpBuffer: LPCVOID,
765-
nNumberOfCharsToWrite: DWORD,
766-
lpNumberOfCharsWritten: LPDWORD,
767-
lpReserved: LPVOID) -> BOOL;
768-
769-
pub fn GetConsoleMode(hConsoleHandle: HANDLE,
770-
lpMode: LPDWORD) -> BOOL;
771772
pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
772773
pub fn SetFileAttributesW(lpFileName: LPCWSTR,
773774
dwFileAttributes: DWORD) -> BOOL;

src/libstd/sys/windows/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,14 @@ pub mod stack_overflow;
3737
pub mod thread;
3838
pub mod thread_local;
3939
pub mod time;
40-
pub mod stdio;
40+
cfg_if! {
41+
if #[cfg(not(target_vendor = "uwp"))] {
42+
pub mod stdio;
43+
} else {
44+
pub mod stdio_uwp;
45+
pub use self::stdio_uwp as stdio;
46+
}
47+
}
4148

4249
#[cfg(not(test))]
4350
pub fn init() {

src/libstd/sys/windows/stdio_uwp.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#![unstable(issue = "0", feature = "windows_stdio")]
2+
3+
use crate::io;
4+
use crate::sys::c;
5+
use crate::sys::handle::Handle;
6+
use crate::mem::ManuallyDrop;
7+
8+
pub struct Stdin {
9+
}
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+
let handle = Handle::new(handle);
30+
ManuallyDrop::new(handle).write(data)
31+
}
32+
33+
impl Stdin {
34+
pub fn new() -> io::Result<Stdin> {
35+
Ok(Stdin { })
36+
}
37+
}
38+
39+
impl io::Read for Stdin {
40+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
41+
let handle = get_handle(c::STD_INPUT_HANDLE)?;
42+
let handle = Handle::new(handle);
43+
ManuallyDrop::new(handle).read(buf)
44+
}
45+
}
46+
47+
impl Stdout {
48+
pub fn new() -> io::Result<Stdout> {
49+
Ok(Stdout)
50+
}
51+
}
52+
53+
impl io::Write for Stdout {
54+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
55+
write(c::STD_OUTPUT_HANDLE, buf)
56+
}
57+
58+
fn flush(&mut self) -> io::Result<()> {
59+
Ok(())
60+
}
61+
}
62+
63+
impl Stderr {
64+
pub fn new() -> io::Result<Stderr> {
65+
Ok(Stderr)
66+
}
67+
}
68+
69+
impl io::Write for Stderr {
70+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
71+
write(c::STD_ERROR_HANDLE, buf)
72+
}
73+
74+
fn flush(&mut self) -> io::Result<()> {
75+
Ok(())
76+
}
77+
}
78+
79+
pub fn is_ebadf(err: &io::Error) -> bool {
80+
err.raw_os_error() == Some(c::ERROR_INVALID_HANDLE as i32)
81+
}
82+
83+
pub fn panic_output() -> Option<impl io::Write> {
84+
Stderr::new().ok()
85+
}

0 commit comments

Comments
 (0)