Skip to content

Commit 668f0d3

Browse files
committed
std: win: Don't use console APIs on UWP
1 parent 4c05073 commit 668f0d3

File tree

3 files changed

+119
-26
lines changed

3 files changed

+119
-26
lines changed

Diff for: src/libstd/sys/windows/c.rs

+26-25
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ pub type ULONG = c_ulong;
3535
pub type LPBOOL = *mut BOOL;
3636
pub type LPBYTE = *mut BYTE;
3737
pub type LPCSTR = *const CHAR;
38-
pub type LPCVOID = *const c_void;
3938
pub type LPCWSTR = *const WCHAR;
4039
pub type LPDWORD = *mut DWORD;
4140
pub type LPHANDLE = *mut HANDLE;
@@ -609,16 +608,6 @@ pub enum EXCEPTION_DISPOSITION {
609608
ExceptionCollidedUnwind
610609
}
611610

612-
#[repr(C)]
613-
#[derive(Copy, Clone)]
614-
pub struct CONSOLE_READCONSOLE_CONTROL {
615-
pub nLength: ULONG,
616-
pub nInitialChars: ULONG,
617-
pub dwCtrlWakeupMask: ULONG,
618-
pub dwControlKeyState: ULONG,
619-
}
620-
pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL;
621-
622611
#[repr(C)]
623612
#[derive(Copy)]
624613
pub struct fd_set {
@@ -642,6 +631,17 @@ pub struct timeval {
642631
// Functions forbidden when targeting UWP
643632
cfg_if::cfg_if! {
644633
if #[cfg(not(target_vendor = "uwp"))] {
634+
#[repr(C)]
635+
#[derive(Copy, Clone)]
636+
pub struct CONSOLE_READCONSOLE_CONTROL {
637+
pub nLength: ULONG,
638+
pub nInitialChars: ULONG,
639+
pub dwCtrlWakeupMask: ULONG,
640+
pub dwControlKeyState: ULONG,
641+
}
642+
643+
pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL;
644+
645645
#[repr(C)]
646646
pub struct BY_HANDLE_FILE_INFORMATION {
647647
pub dwFileAttributes: DWORD,
@@ -657,6 +657,7 @@ if #[cfg(not(target_vendor = "uwp"))] {
657657
}
658658

659659
pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
660+
pub type LPCVOID = *const c_void;
660661

661662
pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
662663

@@ -666,6 +667,20 @@ if #[cfg(not(target_vendor = "uwp"))] {
666667
#[link_name = "SystemFunction036"]
667668
pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN;
668669

670+
pub fn ReadConsoleW(hConsoleInput: HANDLE,
671+
lpBuffer: LPVOID,
672+
nNumberOfCharsToRead: DWORD,
673+
lpNumberOfCharsRead: LPDWORD,
674+
pInputControl: PCONSOLE_READCONSOLE_CONTROL) -> BOOL;
675+
676+
pub fn WriteConsoleW(hConsoleOutput: HANDLE,
677+
lpBuffer: LPCVOID,
678+
nNumberOfCharsToWrite: DWORD,
679+
lpNumberOfCharsWritten: LPDWORD,
680+
lpReserved: LPVOID) -> BOOL;
681+
682+
pub fn GetConsoleMode(hConsoleHandle: HANDLE,
683+
lpMode: LPDWORD) -> BOOL;
669684
// Allowed but unused by UWP
670685
pub fn OpenProcessToken(ProcessHandle: HANDLE,
671686
DesiredAccess: DWORD,
@@ -752,20 +767,6 @@ extern "system" {
752767
pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
753768
pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
754769

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

Diff for: src/libstd/sys/windows/mod.rs

+8-1
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::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() {

Diff for: src/libstd/sys/windows/stdio_uwp.rs

+85
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)