pub type LPBOOL = *mut BOOL;
pub type LPBYTE = *mut BYTE;
pub type LPCSTR = *const CHAR;
-pub type LPCVOID = *const c_void;
pub type LPCWSTR = *const WCHAR;
pub type LPDWORD = *mut DWORD;
pub type LPHANDLE = *mut HANDLE;
ExceptionCollidedUnwind
}
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct CONSOLE_READCONSOLE_CONTROL {
- pub nLength: ULONG,
- pub nInitialChars: ULONG,
- pub dwCtrlWakeupMask: ULONG,
- pub dwControlKeyState: ULONG,
-}
-pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL;
-
#[repr(C)]
#[derive(Copy)]
pub struct fd_set {
// Functions forbidden when targeting UWP
cfg_if::cfg_if! {
if #[cfg(not(target_vendor = "uwp"))] {
+ #[repr(C)]
+ #[derive(Copy, Clone)]
+ pub struct CONSOLE_READCONSOLE_CONTROL {
+ pub nLength: ULONG,
+ pub nInitialChars: ULONG,
+ pub dwCtrlWakeupMask: ULONG,
+ pub dwControlKeyState: ULONG,
+ }
+
+ pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL;
+
#[repr(C)]
pub struct BY_HANDLE_FILE_INFORMATION {
pub dwFileAttributes: DWORD,
}
pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
+ pub type LPCVOID = *const c_void;
pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
#[link_name = "SystemFunction036"]
pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN;
+ pub fn ReadConsoleW(hConsoleInput: HANDLE,
+ lpBuffer: LPVOID,
+ nNumberOfCharsToRead: DWORD,
+ lpNumberOfCharsRead: LPDWORD,
+ pInputControl: PCONSOLE_READCONSOLE_CONTROL) -> BOOL;
+
+ pub fn WriteConsoleW(hConsoleOutput: HANDLE,
+ lpBuffer: LPCVOID,
+ nNumberOfCharsToWrite: DWORD,
+ lpNumberOfCharsWritten: LPDWORD,
+ lpReserved: LPVOID) -> BOOL;
+
+ pub fn GetConsoleMode(hConsoleHandle: HANDLE,
+ lpMode: LPDWORD) -> BOOL;
// Allowed but unused by UWP
pub fn OpenProcessToken(ProcessHandle: HANDLE,
DesiredAccess: DWORD,
pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
- pub fn ReadConsoleW(hConsoleInput: HANDLE,
- lpBuffer: LPVOID,
- nNumberOfCharsToRead: DWORD,
- lpNumberOfCharsRead: LPDWORD,
- pInputControl: PCONSOLE_READCONSOLE_CONTROL) -> BOOL;
-
- pub fn WriteConsoleW(hConsoleOutput: HANDLE,
- lpBuffer: LPCVOID,
- nNumberOfCharsToWrite: DWORD,
- lpNumberOfCharsWritten: LPDWORD,
- lpReserved: LPVOID) -> BOOL;
-
- pub fn GetConsoleMode(hConsoleHandle: HANDLE,
- lpMode: LPDWORD) -> BOOL;
pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
pub fn SetFileAttributesW(lpFileName: LPCWSTR,
dwFileAttributes: DWORD) -> BOOL;
--- /dev/null
+#![unstable(issue = "0", feature = "windows_stdio")]
+
+use crate::io;
+use crate::sys::c;
+use crate::sys::handle::Handle;
+use crate::mem::ManuallyDrop;
+
+pub struct Stdin {
+}
+pub struct Stdout;
+pub struct Stderr;
+
+const MAX_BUFFER_SIZE: usize = 8192;
+pub const STDIN_BUF_SIZE: usize = MAX_BUFFER_SIZE / 2 * 3;
+
+pub fn get_handle(handle_id: c::DWORD) -> io::Result<c::HANDLE> {
+ let handle = unsafe { c::GetStdHandle(handle_id) };
+ if handle == c::INVALID_HANDLE_VALUE {
+ Err(io::Error::last_os_error())
+ } else if handle.is_null() {
+ Err(io::Error::from_raw_os_error(c::ERROR_INVALID_HANDLE as i32))
+ } else {
+ Ok(handle)
+ }
+}
+
+fn write(handle_id: c::DWORD, data: &[u8]) -> io::Result<usize> {
+ let handle = get_handle(handle_id)?;
+ let handle = Handle::new(handle);
+ ManuallyDrop::new(handle).write(data)
+}
+
+impl Stdin {
+ pub fn new() -> io::Result<Stdin> {
+ Ok(Stdin { })
+ }
+}
+
+impl io::Read for Stdin {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ let handle = get_handle(c::STD_INPUT_HANDLE)?;
+ let handle = Handle::new(handle);
+ ManuallyDrop::new(handle).read(buf)
+ }
+}
+
+impl Stdout {
+ pub fn new() -> io::Result<Stdout> {
+ Ok(Stdout)
+ }
+}
+
+impl io::Write for Stdout {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ write(c::STD_OUTPUT_HANDLE, buf)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ Ok(())
+ }
+}
+
+impl Stderr {
+ pub fn new() -> io::Result<Stderr> {
+ Ok(Stderr)
+ }
+}
+
+impl io::Write for Stderr {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ write(c::STD_ERROR_HANDLE, buf)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ Ok(())
+ }
+}
+
+pub fn is_ebadf(err: &io::Error) -> bool {
+ err.raw_os_error() == Some(c::ERROR_INVALID_HANDLE as i32)
+}
+
+pub fn panic_output() -> Option<impl io::Write> {
+ Stderr::new().ok()
+}