From 188cfeccbfe8f5b8e51e579ab3bf99a384bde843 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Tue, 8 Apr 2025 21:51:16 +0530 Subject: [PATCH 1/2] std: sys: stdio: uefi: Implement is_ebadf - NOT_READY status should be used here. Signed-off-by: Ayush Singh --- library/std/src/sys/stdio/uefi.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/stdio/uefi.rs b/library/std/src/sys/stdio/uefi.rs index 257e321dd03d7..7fe445a7358f9 100644 --- a/library/std/src/sys/stdio/uefi.rs +++ b/library/std/src/sys/stdio/uefi.rs @@ -142,8 +142,12 @@ impl io::Write for Stderr { // UTF-16 character should occupy 4 bytes at most in UTF-8 pub const STDIN_BUF_SIZE: usize = 4; -pub fn is_ebadf(_err: &io::Error) -> bool { - false +pub fn is_ebadf(err: &io::Error) -> bool { + if let Some(x) = err.raw_os_error() { + r_efi::efi::Status::NOT_READY.as_usize() == x + } else { + false + } } pub fn panic_output() -> Option { From 0b47e50344e406f9db49170054d3daad17a7a06b Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Tue, 8 Apr 2025 22:00:28 +0530 Subject: [PATCH 2/2] std: sys: stdio: uefi: Do not retry on NOT_READY Since NOT_READY is now used to signal read 0. Remove the loop which would always retry on NOT_READY status. Instead, use the following algorithm: 1. Try reading any pending characters. Return if present. 2. If no pending character, NOT_READY is returned. 3. Wait for key. 4. Return the key or error. Signed-off-by: Ayush Singh --- library/std/src/sys/stdio/uefi.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/library/std/src/sys/stdio/uefi.rs b/library/std/src/sys/stdio/uefi.rs index 7fe445a7358f9..ce0db1666e618 100644 --- a/library/std/src/sys/stdio/uefi.rs +++ b/library/std/src/sys/stdio/uefi.rs @@ -184,13 +184,17 @@ unsafe fn simple_text_output( fn simple_text_input_read( stdin: *mut r_efi::protocols::simple_text_input::Protocol, ) -> io::Result { - loop { - match read_key_stroke(stdin) { - Ok(x) => return Ok(x.unicode_char), - Err(e) if e == r_efi::efi::Status::NOT_READY => wait_stdin(stdin)?, - Err(e) => return Err(io::Error::from_raw_os_error(e.as_usize())), - } + // Try reading any pending keys. Else wait for a new character + match read_key_stroke(stdin) { + Ok(x) => return Ok(x.unicode_char), + Err(e) if e == r_efi::efi::Status::NOT_READY => wait_stdin(stdin)?, + Err(e) => return Err(io::Error::from_raw_os_error(e.as_usize())), } + + // Try reading a key after the wait. + read_key_stroke(stdin) + .map(|x| x.unicode_char) + .map_err(|e| io::Error::from_raw_os_error(e.as_usize())) } fn wait_stdin(stdin: *mut r_efi::protocols::simple_text_input::Protocol) -> io::Result<()> {