Skip to content

Commit 4fff642

Browse files
committed
Auto merge of rust-lang#136769 - thaliaarchi:io-optional-methods/stdio, r=<try>
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 rust-lang#136756. try-job: x86_64-msvc-1
2 parents 2a1c8be + 46e3e46 commit 4fff642

File tree

7 files changed

+139
-160
lines changed

7 files changed

+139
-160
lines changed

library/std/src/io/stdio.rs

+35-28
Original file line numberDiff line numberDiff line change
@@ -97,39 +97,53 @@ const fn stderr_raw() -> StderrRaw {
9797

9898
impl Read for StdinRaw {
9999
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
100-
handle_ebadf(self.0.read(buf), 0)
100+
handle_ebadf(self.0.read(buf), || Ok(0))
101101
}
102102

103103
fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
104-
handle_ebadf(self.0.read_buf(buf), ())
104+
handle_ebadf(self.0.read_buf(buf), || Ok(()))
105105
}
106106

107107
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
108-
handle_ebadf(self.0.read_vectored(bufs), 0)
108+
handle_ebadf(self.0.read_vectored(bufs), || Ok(0))
109109
}
110110

111111
#[inline]
112112
fn is_read_vectored(&self) -> bool {
113113
self.0.is_read_vectored()
114114
}
115115

116+
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
117+
if buf.is_empty() {
118+
return Ok(());
119+
}
120+
handle_ebadf(self.0.read_exact(buf), || Err(io::Error::READ_EXACT_EOF))
121+
}
122+
123+
fn read_buf_exact(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> {
124+
if buf.capacity() == 0 {
125+
return Ok(());
126+
}
127+
handle_ebadf(self.0.read_buf_exact(buf), || Err(io::Error::READ_EXACT_EOF))
128+
}
129+
116130
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
117-
handle_ebadf(self.0.read_to_end(buf), 0)
131+
handle_ebadf(self.0.read_to_end(buf), || Ok(0))
118132
}
119133

120134
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
121-
handle_ebadf(self.0.read_to_string(buf), 0)
135+
handle_ebadf(self.0.read_to_string(buf), || Ok(0))
122136
}
123137
}
124138

125139
impl Write for StdoutRaw {
126140
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
127-
handle_ebadf(self.0.write(buf), buf.len())
141+
handle_ebadf(self.0.write(buf), || Ok(buf.len()))
128142
}
129143

130144
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
131-
let total = || bufs.iter().map(|b| b.len()).sum();
132-
handle_ebadf_lazy(self.0.write_vectored(bufs), total)
145+
let total = || Ok(bufs.iter().map(|b| b.len()).sum());
146+
handle_ebadf(self.0.write_vectored(bufs), total)
133147
}
134148

135149
#[inline]
@@ -138,30 +152,30 @@ impl Write for StdoutRaw {
138152
}
139153

140154
fn flush(&mut self) -> io::Result<()> {
141-
handle_ebadf(self.0.flush(), ())
155+
handle_ebadf(self.0.flush(), || Ok(()))
142156
}
143157

144158
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
145-
handle_ebadf(self.0.write_all(buf), ())
159+
handle_ebadf(self.0.write_all(buf), || Ok(()))
146160
}
147161

148162
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
149-
handle_ebadf(self.0.write_all_vectored(bufs), ())
163+
handle_ebadf(self.0.write_all_vectored(bufs), || Ok(()))
150164
}
151165

152166
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
153-
handle_ebadf(self.0.write_fmt(fmt), ())
167+
handle_ebadf(self.0.write_fmt(fmt), || Ok(()))
154168
}
155169
}
156170

157171
impl Write for StderrRaw {
158172
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
159-
handle_ebadf(self.0.write(buf), buf.len())
173+
handle_ebadf(self.0.write(buf), || Ok(buf.len()))
160174
}
161175

162176
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
163-
let total = || bufs.iter().map(|b| b.len()).sum();
164-
handle_ebadf_lazy(self.0.write_vectored(bufs), total)
177+
let total = || Ok(bufs.iter().map(|b| b.len()).sum());
178+
handle_ebadf(self.0.write_vectored(bufs), total)
165179
}
166180

167181
#[inline]
@@ -170,32 +184,25 @@ impl Write for StderrRaw {
170184
}
171185

172186
fn flush(&mut self) -> io::Result<()> {
173-
handle_ebadf(self.0.flush(), ())
187+
handle_ebadf(self.0.flush(), || Ok(()))
174188
}
175189

176190
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
177-
handle_ebadf(self.0.write_all(buf), ())
191+
handle_ebadf(self.0.write_all(buf), || Ok(()))
178192
}
179193

180194
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
181-
handle_ebadf(self.0.write_all_vectored(bufs), ())
195+
handle_ebadf(self.0.write_all_vectored(bufs), || Ok(()))
182196
}
183197

184198
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
185-
handle_ebadf(self.0.write_fmt(fmt), ())
186-
}
187-
}
188-
189-
fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
190-
match r {
191-
Err(ref e) if stdio::is_ebadf(e) => Ok(default),
192-
r => r,
199+
handle_ebadf(self.0.write_fmt(fmt), || Ok(()))
193200
}
194201
}
195202

196-
fn handle_ebadf_lazy<T>(r: io::Result<T>, default: impl FnOnce() -> T) -> io::Result<T> {
203+
fn handle_ebadf<T>(r: io::Result<T>, default: impl FnOnce() -> io::Result<T>) -> io::Result<T> {
197204
match r {
198-
Err(ref e) if stdio::is_ebadf(e) => Ok(default()),
205+
Err(ref e) if stdio::is_ebadf(e) => default(),
199206
r => r,
200207
}
201208
}

library/std/src/sys/stdio/sgx.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ use fortanix_sgx_abi as abi;
33
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
44
use crate::sys::fd::FileDesc;
55

6-
pub struct Stdin(());
7-
pub struct Stdout(());
8-
pub struct Stderr(());
6+
pub struct Stdin;
7+
pub struct Stdout;
8+
pub struct Stderr;
99

1010
fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R {
1111
let fd = FileDesc::new(fd);
@@ -16,7 +16,7 @@ fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R {
1616

1717
impl Stdin {
1818
pub const fn new() -> Stdin {
19-
Stdin(())
19+
Stdin
2020
}
2121
}
2222

@@ -41,7 +41,7 @@ impl io::Read for Stdin {
4141

4242
impl Stdout {
4343
pub const fn new() -> Stdout {
44-
Stdout(())
44+
Stdout
4545
}
4646
}
4747

@@ -66,7 +66,7 @@ impl io::Write for Stdout {
6666

6767
impl Stderr {
6868
pub const fn new() -> Stderr {
69-
Stderr(())
69+
Stderr
7070
}
7171
}
7272

library/std/src/sys/stdio/solid.rs

+8-51
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,13 @@
1+
#[expect(dead_code)]
2+
#[path = "unsupported.rs"]
3+
mod unsupported_stdio;
4+
15
use crate::io;
26
use crate::sys::pal::abi;
37

4-
pub struct Stdin;
8+
pub type Stdin = unsupported_stdio::Stdin;
59
pub struct Stdout;
6-
pub struct Stderr;
7-
struct PanicOutput;
8-
9-
impl Stdin {
10-
pub const fn new() -> Stdin {
11-
Stdin
12-
}
13-
}
14-
15-
impl io::Read for Stdin {
16-
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
17-
Ok(0)
18-
}
19-
}
10+
pub type Stderr = Stdout;
2011

2112
impl Stdout {
2213
pub const fn new() -> Stdout {
@@ -35,46 +26,12 @@ impl io::Write for Stdout {
3526
}
3627
}
3728

38-
impl Stderr {
39-
pub const fn new() -> Stderr {
40-
Stderr
41-
}
42-
}
43-
44-
impl io::Write for Stderr {
45-
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
46-
unsafe { abi::SOLID_LOG_write(buf.as_ptr(), buf.len()) };
47-
Ok(buf.len())
48-
}
49-
50-
fn flush(&mut self) -> io::Result<()> {
51-
Ok(())
52-
}
53-
}
54-
55-
impl PanicOutput {
56-
pub const fn new() -> PanicOutput {
57-
PanicOutput
58-
}
59-
}
60-
61-
impl io::Write for PanicOutput {
62-
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
63-
unsafe { abi::SOLID_LOG_write(buf.as_ptr(), buf.len()) };
64-
Ok(buf.len())
65-
}
66-
67-
fn flush(&mut self) -> io::Result<()> {
68-
Ok(())
69-
}
70-
}
71-
72-
pub const STDIN_BUF_SIZE: usize = 0;
29+
pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE;
7330

7431
pub fn is_ebadf(_err: &io::Error) -> bool {
7532
true
7633
}
7734

7835
pub fn panic_output() -> Option<impl io::Write> {
79-
Some(PanicOutput::new())
36+
Some(Stderr::new())
8037
}

library/std/src/sys/stdio/teeos.rs

+13-40
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
#![deny(unsafe_op_in_unsafe_fn)]
22

3+
#[expect(dead_code)]
4+
#[path = "unsupported.rs"]
5+
mod unsupported_stdio;
6+
37
use core::arch::asm;
48

59
use crate::io;
610

7-
pub struct Stdin;
11+
pub type Stdin = unsupported_stdio::Stdin;
812
pub struct Stdout;
9-
pub struct Stderr;
13+
pub type Stderr = Stdout;
1014

1115
const KCALL_DEBUG_CMD_PUT_BYTES: i64 = 2;
1216

@@ -25,27 +29,6 @@ unsafe fn debug_call(cap_ref: u64, call_no: i64, arg1: u64, arg2: u64) -> i32 {
2529
ret as i32
2630
}
2731

28-
fn print_buf(s: &[u8]) -> io::Result<usize> {
29-
// Corresponds to `HM_DEBUG_PUT_BYTES_LIMIT`.
30-
const MAX_LEN: usize = 512;
31-
let len = if s.len() > MAX_LEN { MAX_LEN } else { s.len() };
32-
let result = unsafe { debug_call(0, KCALL_DEBUG_CMD_PUT_BYTES, s.as_ptr() as u64, len as u64) };
33-
34-
if result == 0 { Ok(len) } else { Err(io::Error::from(io::ErrorKind::InvalidInput)) }
35-
}
36-
37-
impl Stdin {
38-
pub const fn new() -> Stdin {
39-
Stdin
40-
}
41-
}
42-
43-
impl io::Read for Stdin {
44-
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
45-
Ok(0)
46-
}
47-
}
48-
4932
impl Stdout {
5033
pub const fn new() -> Stdout {
5134
Stdout
@@ -54,31 +37,21 @@ impl Stdout {
5437

5538
impl io::Write for Stdout {
5639
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
57-
print_buf(buf)
58-
}
59-
60-
fn flush(&mut self) -> io::Result<()> {
61-
Ok(())
62-
}
63-
}
40+
// Corresponds to `HM_DEBUG_PUT_BYTES_LIMIT`.
41+
const MAX_LEN: usize = 512;
42+
let len = buf.len().min(MAX_LEN);
43+
let result =
44+
unsafe { debug_call(0, KCALL_DEBUG_CMD_PUT_BYTES, buf.as_ptr() as u64, len as u64) };
6445

65-
impl Stderr {
66-
pub const fn new() -> Stderr {
67-
Stderr
68-
}
69-
}
70-
71-
impl io::Write for Stderr {
72-
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
73-
print_buf(buf)
46+
if result == 0 { Ok(len) } else { Err(io::Error::from(io::ErrorKind::InvalidInput)) }
7447
}
7548

7649
fn flush(&mut self) -> io::Result<()> {
7750
Ok(())
7851
}
7952
}
8053

81-
pub const STDIN_BUF_SIZE: usize = 0;
54+
pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE;
8255

8356
pub fn is_ebadf(err: &io::Error) -> bool {
8457
err.raw_os_error() == Some(libc::EBADF as i32)

library/std/src/sys/stdio/unix.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ use crate::os::hermit::io::FromRawFd;
1111
use crate::os::unix::io::FromRawFd;
1212
use crate::sys::fd::FileDesc;
1313

14-
pub struct Stdin(());
15-
pub struct Stdout(());
16-
pub struct Stderr(());
14+
pub struct Stdin;
15+
pub struct Stdout;
16+
pub struct Stderr;
1717

1818
impl Stdin {
1919
pub const fn new() -> Stdin {
20-
Stdin(())
20+
Stdin
2121
}
2222
}
2323

@@ -42,7 +42,7 @@ impl io::Read for Stdin {
4242

4343
impl Stdout {
4444
pub const fn new() -> Stdout {
45-
Stdout(())
45+
Stdout
4646
}
4747
}
4848

@@ -68,7 +68,7 @@ impl io::Write for Stdout {
6868

6969
impl Stderr {
7070
pub const fn new() -> Stderr {
71-
Stderr(())
71+
Stderr
7272
}
7373
}
7474

0 commit comments

Comments
 (0)