1 // Copyright 2022 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use std::io::Error; 6 use std::io::Read; 7 use std::io::Result; 8 9 use winapi::shared::minwindef::LPVOID; 10 use winapi::shared::ntdef::NULL; 11 use winapi::um::fileapi::ReadFile; 12 use winapi::um::minwinbase::LPOVERLAPPED; 13 14 use crate::AsRawDescriptor; 15 use crate::ReadNotifier; 16 17 pub struct Console(std::io::Stdin); 18 19 impl Console { new() -> Self20 pub fn new() -> Self { 21 Self(std::io::stdin()) 22 } 23 } 24 25 impl Read for Console { read(&mut self, out: &mut [u8]) -> Result<usize>26 fn read(&mut self, out: &mut [u8]) -> Result<usize> { 27 let mut num_of_bytes_read: u32 = 0; 28 // SAFETY: 29 // Safe because `out` is guarenteed to be a valid mutable array 30 // and `num_of_bytes_read` is a valid u32. 31 let res = unsafe { 32 ReadFile( 33 self.0.as_raw_descriptor(), 34 out.as_mut_ptr() as LPVOID, 35 out.len() as u32, 36 &mut num_of_bytes_read, 37 NULL as LPOVERLAPPED, 38 ) 39 }; 40 let error = Error::last_os_error(); 41 if res == 0 { 42 Err(error) 43 } else { 44 Ok(num_of_bytes_read as usize) 45 } 46 } 47 } 48 49 impl ReadNotifier for Console { get_read_notifier(&self) -> &dyn AsRawDescriptor50 fn get_read_notifier(&self) -> &dyn AsRawDescriptor { 51 &self.0 52 } 53 } 54 55 impl Default for Console { default() -> Self56 fn default() -> Self { 57 Self::new() 58 } 59 } 60