diff options
| author | bors <bors@rust-lang.org> | 2025-03-23 06:23:51 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-03-23 06:23:51 +0000 |
| commit | 60a3084f64607e86dd7715d72f11764cd500c364 (patch) | |
| tree | b6abe6c3d8f0e42e6cea362f761a29f080c23789 /library/std/src | |
| parent | f08d5c01e69436891ff1c181385d0e078a8482ec (diff) | |
| parent | f6e90d804a82cce1606596f6116402843794deb3 (diff) | |
| download | rust-60a3084f64607e86dd7715d72f11764cd500c364.tar.gz rust-60a3084f64607e86dd7715d72f11764cd500c364.zip | |
Auto merge of #136769 - thaliaarchi:io-optional-methods/stdio, r=joboet
Provide optional `Read`/`Write` methods for stdio Override more of the default methods for `io::Read` and `io::Write` for stdio types, when efficient to do so, and deduplicate unsupported types. Tracked in https://github.com/rust-lang/rust/issues/136756. try-job: x86_64-msvc-1
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/io/stdio.rs | 63 | ||||
| -rw-r--r-- | library/std/src/sys/stdio/sgx.rs | 12 | ||||
| -rw-r--r-- | library/std/src/sys/stdio/solid.rs | 59 | ||||
| -rw-r--r-- | library/std/src/sys/stdio/teeos.rs | 53 | ||||
| -rw-r--r-- | library/std/src/sys/stdio/unix.rs | 12 | ||||
| -rw-r--r-- | library/std/src/sys/stdio/unsupported.rs | 71 | ||||
| -rw-r--r-- | library/std/src/sys/stdio/xous.rs | 27 |
7 files changed, 136 insertions, 161 deletions
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index ce46241f8e8..8fc16331339 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -97,15 +97,15 @@ const fn stderr_raw() -> StderrRaw { impl Read for StdinRaw { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - handle_ebadf(self.0.read(buf), 0) + handle_ebadf(self.0.read(buf), || Ok(0)) } fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { - handle_ebadf(self.0.read_buf(buf), ()) + handle_ebadf(self.0.read_buf(buf), || Ok(())) } fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - handle_ebadf(self.0.read_vectored(bufs), 0) + handle_ebadf(self.0.read_vectored(bufs), || Ok(0)) } #[inline] @@ -113,23 +113,37 @@ impl Read for StdinRaw { self.0.is_read_vectored() } + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + if buf.is_empty() { + return Ok(()); + } + handle_ebadf(self.0.read_exact(buf), || Err(io::Error::READ_EXACT_EOF)) + } + + fn read_buf_exact(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + if buf.capacity() == 0 { + return Ok(()); + } + handle_ebadf(self.0.read_buf_exact(buf), || Err(io::Error::READ_EXACT_EOF)) + } + fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { - handle_ebadf(self.0.read_to_end(buf), 0) + handle_ebadf(self.0.read_to_end(buf), || Ok(0)) } fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { - handle_ebadf(self.0.read_to_string(buf), 0) + handle_ebadf(self.0.read_to_string(buf), || Ok(0)) } } impl Write for StdoutRaw { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - handle_ebadf(self.0.write(buf), buf.len()) + handle_ebadf(self.0.write(buf), || Ok(buf.len())) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - let total = || bufs.iter().map(|b| b.len()).sum(); - handle_ebadf_lazy(self.0.write_vectored(bufs), total) + let total = || Ok(bufs.iter().map(|b| b.len()).sum()); + handle_ebadf(self.0.write_vectored(bufs), total) } #[inline] @@ -138,30 +152,30 @@ impl Write for StdoutRaw { } fn flush(&mut self) -> io::Result<()> { - handle_ebadf(self.0.flush(), ()) + handle_ebadf(self.0.flush(), || Ok(())) } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - handle_ebadf(self.0.write_all(buf), ()) + handle_ebadf(self.0.write_all(buf), || Ok(())) } fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { - handle_ebadf(self.0.write_all_vectored(bufs), ()) + handle_ebadf(self.0.write_all_vectored(bufs), || Ok(())) } fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { - handle_ebadf(self.0.write_fmt(fmt), ()) + handle_ebadf(self.0.write_fmt(fmt), || Ok(())) } } impl Write for StderrRaw { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - handle_ebadf(self.0.write(buf), buf.len()) + handle_ebadf(self.0.write(buf), || Ok(buf.len())) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - let total = || bufs.iter().map(|b| b.len()).sum(); - handle_ebadf_lazy(self.0.write_vectored(bufs), total) + let total = || Ok(bufs.iter().map(|b| b.len()).sum()); + handle_ebadf(self.0.write_vectored(bufs), total) } #[inline] @@ -170,32 +184,25 @@ impl Write for StderrRaw { } fn flush(&mut self) -> io::Result<()> { - handle_ebadf(self.0.flush(), ()) + handle_ebadf(self.0.flush(), || Ok(())) } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - handle_ebadf(self.0.write_all(buf), ()) + handle_ebadf(self.0.write_all(buf), || Ok(())) } fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { - handle_ebadf(self.0.write_all_vectored(bufs), ()) + handle_ebadf(self.0.write_all_vectored(bufs), || Ok(())) } fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { - handle_ebadf(self.0.write_fmt(fmt), ()) - } -} - -fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> { - match r { - Err(ref e) if stdio::is_ebadf(e) => Ok(default), - r => r, + handle_ebadf(self.0.write_fmt(fmt), || Ok(())) } } -fn handle_ebadf_lazy<T>(r: io::Result<T>, default: impl FnOnce() -> T) -> io::Result<T> { +fn handle_ebadf<T>(r: io::Result<T>, default: impl FnOnce() -> io::Result<T>) -> io::Result<T> { match r { - Err(ref e) if stdio::is_ebadf(e) => Ok(default()), + Err(ref e) if stdio::is_ebadf(e) => default(), r => r, } } diff --git a/library/std/src/sys/stdio/sgx.rs b/library/std/src/sys/stdio/sgx.rs index 1894c098d18..2cf47f49192 100644 --- a/library/std/src/sys/stdio/sgx.rs +++ b/library/std/src/sys/stdio/sgx.rs @@ -3,9 +3,9 @@ use fortanix_sgx_abi as abi; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::sys::fd::FileDesc; -pub struct Stdin(()); -pub struct Stdout(()); -pub struct Stderr(()); +pub struct Stdin; +pub struct Stdout; +pub struct Stderr; fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R { let fd = FileDesc::new(fd); @@ -16,7 +16,7 @@ fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R { impl Stdin { pub const fn new() -> Stdin { - Stdin(()) + Stdin } } @@ -41,7 +41,7 @@ impl io::Read for Stdin { impl Stdout { pub const fn new() -> Stdout { - Stdout(()) + Stdout } } @@ -66,7 +66,7 @@ impl io::Write for Stdout { impl Stderr { pub const fn new() -> Stderr { - Stderr(()) + Stderr } } diff --git a/library/std/src/sys/stdio/solid.rs b/library/std/src/sys/stdio/solid.rs index a2ff4bb212f..55daf0b54b9 100644 --- a/library/std/src/sys/stdio/solid.rs +++ b/library/std/src/sys/stdio/solid.rs @@ -1,22 +1,13 @@ +#[expect(dead_code)] +#[path = "unsupported.rs"] +mod unsupported_stdio; + use crate::io; use crate::sys::pal::abi; -pub struct Stdin; +pub type Stdin = unsupported_stdio::Stdin; pub struct Stdout; -pub struct Stderr; -struct PanicOutput; - -impl Stdin { - pub const fn new() -> Stdin { - Stdin - } -} - -impl io::Read for Stdin { - fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { - Ok(0) - } -} +pub type Stderr = Stdout; impl Stdout { pub const fn new() -> Stdout { @@ -35,46 +26,12 @@ impl io::Write for Stdout { } } -impl Stderr { - pub const fn new() -> Stderr { - Stderr - } -} - -impl io::Write for Stderr { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - unsafe { abi::SOLID_LOG_write(buf.as_ptr(), buf.len()) }; - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl PanicOutput { - pub const fn new() -> PanicOutput { - PanicOutput - } -} - -impl io::Write for PanicOutput { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - unsafe { abi::SOLID_LOG_write(buf.as_ptr(), buf.len()) }; - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -pub const STDIN_BUF_SIZE: usize = 0; +pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE; pub fn is_ebadf(_err: &io::Error) -> bool { true } pub fn panic_output() -> Option<impl io::Write> { - Some(PanicOutput::new()) + Some(Stderr::new()) } diff --git a/library/std/src/sys/stdio/teeos.rs b/library/std/src/sys/stdio/teeos.rs index 67e251812da..27b3292bf8f 100644 --- a/library/std/src/sys/stdio/teeos.rs +++ b/library/std/src/sys/stdio/teeos.rs @@ -1,12 +1,16 @@ #![deny(unsafe_op_in_unsafe_fn)] +#[expect(dead_code)] +#[path = "unsupported.rs"] +mod unsupported_stdio; + use core::arch::asm; use crate::io; -pub struct Stdin; +pub type Stdin = unsupported_stdio::Stdin; pub struct Stdout; -pub struct Stderr; +pub type Stderr = Stdout; const KCALL_DEBUG_CMD_PUT_BYTES: i64 = 2; @@ -25,27 +29,6 @@ unsafe fn debug_call(cap_ref: u64, call_no: i64, arg1: u64, arg2: u64) -> i32 { ret as i32 } -fn print_buf(s: &[u8]) -> io::Result<usize> { - // Corresponds to `HM_DEBUG_PUT_BYTES_LIMIT`. - const MAX_LEN: usize = 512; - let len = if s.len() > MAX_LEN { MAX_LEN } else { s.len() }; - let result = unsafe { debug_call(0, KCALL_DEBUG_CMD_PUT_BYTES, s.as_ptr() as u64, len as u64) }; - - if result == 0 { Ok(len) } else { Err(io::Error::from(io::ErrorKind::InvalidInput)) } -} - -impl Stdin { - pub const fn new() -> Stdin { - Stdin - } -} - -impl io::Read for Stdin { - fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { - Ok(0) - } -} - impl Stdout { pub const fn new() -> Stdout { Stdout @@ -54,23 +37,13 @@ impl Stdout { impl io::Write for Stdout { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - print_buf(buf) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} + // 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) }; -impl Stderr { - pub const fn new() -> Stderr { - Stderr - } -} - -impl io::Write for Stderr { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - print_buf(buf) + if result == 0 { Ok(len) } else { Err(io::Error::from(io::ErrorKind::InvalidInput)) } } fn flush(&mut self) -> io::Result<()> { @@ -78,7 +51,7 @@ impl io::Write for Stderr { } } -pub const STDIN_BUF_SIZE: usize = 0; +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) diff --git a/library/std/src/sys/stdio/unix.rs b/library/std/src/sys/stdio/unix.rs index 08a06e0da9f..8535e3539e9 100644 --- a/library/std/src/sys/stdio/unix.rs +++ b/library/std/src/sys/stdio/unix.rs @@ -11,13 +11,13 @@ use crate::os::hermit::io::FromRawFd; use crate::os::unix::io::FromRawFd; use crate::sys::fd::FileDesc; -pub struct Stdin(()); -pub struct Stdout(()); -pub struct Stderr(()); +pub struct Stdin; +pub struct Stdout; +pub struct Stderr; impl Stdin { pub const fn new() -> Stdin { - Stdin(()) + Stdin } } @@ -42,7 +42,7 @@ impl io::Read for Stdin { impl Stdout { pub const fn new() -> Stdout { - Stdout(()) + Stdout } } @@ -68,7 +68,7 @@ impl io::Write for Stdout { impl Stderr { pub const fn new() -> Stderr { - Stderr(()) + Stderr } } diff --git a/library/std/src/sys/stdio/unsupported.rs b/library/std/src/sys/stdio/unsupported.rs index b5e3f5be988..177264f5c10 100644 --- a/library/std/src/sys/stdio/unsupported.rs +++ b/library/std/src/sys/stdio/unsupported.rs @@ -1,8 +1,8 @@ -use crate::io; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; pub struct Stdin; pub struct Stdout; -pub struct Stderr; +pub type Stderr = Stdout; impl Stdin { pub const fn new() -> Stdin { @@ -11,9 +11,47 @@ impl Stdin { } impl io::Read for Stdin { + #[inline] fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) } + + #[inline] + fn read_buf(&mut self, _cursor: BorrowedCursor<'_>) -> io::Result<()> { + Ok(()) + } + + #[inline] + fn read_vectored(&mut self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { + Ok(0) + } + + #[inline] + fn is_read_vectored(&self) -> bool { + // Do not force `Chain<Empty, T>` or `Chain<T, Empty>` to use vectored + // reads, unless the other reader is vectored. + false + } + + #[inline] + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + if !buf.is_empty() { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) } + } + + #[inline] + fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> { + if cursor.capacity() != 0 { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) } + } + + #[inline] + fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> { + Ok(0) + } + + #[inline] + fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> { + Ok(0) + } } impl Stdout { @@ -23,26 +61,35 @@ impl Stdout { } impl io::Write for Stdout { + #[inline] fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) } - fn flush(&mut self) -> io::Result<()> { - Ok(()) + #[inline] + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { + let total_len = bufs.iter().map(|b| b.len()).sum(); + Ok(total_len) } -} -impl Stderr { - pub const fn new() -> Stderr { - Stderr + #[inline] + fn is_write_vectored(&self) -> bool { + true } -} -impl io::Write for Stderr { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - Ok(buf.len()) + #[inline] + fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> { + Ok(()) } + #[inline] + fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + Ok(()) + } + + // Keep the default write_fmt so the `fmt::Arguments` are still evaluated. + + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) } diff --git a/library/std/src/sys/stdio/xous.rs b/library/std/src/sys/stdio/xous.rs index 71736145221..a92167642b7 100644 --- a/library/std/src/sys/stdio/xous.rs +++ b/library/std/src/sys/stdio/xous.rs @@ -1,27 +1,18 @@ -use crate::io; - -pub struct Stdin; -pub struct Stdout {} -pub struct Stderr; +#[expect(dead_code)] +#[path = "unsupported.rs"] +mod unsupported_stdio; +use crate::io; use crate::os::xous::ffi::{Connection, lend, try_lend, try_scalar}; use crate::os::xous::services::{LogLend, LogScalar, log_server, try_connect}; -impl Stdin { - pub const fn new() -> Stdin { - Stdin - } -} - -impl io::Read for Stdin { - fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { - Ok(0) - } -} +pub type Stdin = unsupported_stdio::Stdin; +pub struct Stdout; +pub struct Stderr; impl Stdout { pub const fn new() -> Stdout { - Stdout {} + Stdout } } @@ -73,7 +64,7 @@ impl io::Write for Stderr { } } -pub const STDIN_BUF_SIZE: usize = 0; +pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE; pub fn is_ebadf(_err: &io::Error) -> bool { true |
