| #![deny(unsafe_op_in_unsafe_fn)] | |
| #[expect(dead_code)] | |
| #[path = "unsupported.rs"] | |
| mod unsupported_stdio; | |
| use core::arch::asm; | |
| use crate::io; | |
| pub type Stdin = unsupported_stdio::Stdin; | |
| pub struct Stdout; | |
| pub type Stderr = Stdout; | |
| const KCALL_DEBUG_CMD_PUT_BYTES: i64 = 2; | |
| unsafe fn debug_call(cap_ref: u64, call_no: i64, arg1: u64, arg2: u64) -> i32 { | |
| let ret: u64; | |
| unsafe { | |
| asm!( | |
| "svc #99", | |
| inout("x0") cap_ref => ret, | |
| in("x1") call_no, | |
| in("x2") arg1, | |
| in("x3") arg2, | |
| ); | |
| } | |
| ret as i32 | |
| } | |
| impl Stdout { | |
| pub const fn new() -> Stdout { | |
| Stdout | |
| } | |
| } | |
| impl io::Write for Stdout { | |
| fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
| // Corresponds to `HM_DEBUG_PUT_BYTES_LIMIT`. | |
| const MAX_LEN: usize = 512; | |
| let len = buf.len().min(MAX_LEN); | |
| let result = | |
| unsafe { debug_call(0, KCALL_DEBUG_CMD_PUT_BYTES, buf.as_ptr() as u64, len as u64) }; | |
| if result == 0 { Ok(len) } else { Err(io::Error::from(io::ErrorKind::InvalidInput)) } | |
| } | |
| fn flush(&mut self) -> io::Result<()> { | |
| Ok(()) | |
| } | |
| } | |
| pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE; | |
| pub fn is_ebadf(err: &io::Error) -> bool { | |
| err.raw_os_error() == Some(libc::EBADF as i32) | |
| } | |
| pub fn panic_output() -> Option<impl io::Write> { | |
| Some(Stderr::new()) | |
| } |