Implement exact reads for StdinRaw

This commit is contained in:
Thalia Archibald 2025-02-09 02:02:42 -08:00
parent bd49a4beb7
commit ec4beda5d2

View file

@ -97,15 +97,15 @@ const fn stderr_raw() -> StderrRaw {
impl Read for StdinRaw { impl Read for StdinRaw {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { 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<()> { 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> { 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] #[inline]
@ -113,23 +113,37 @@ impl Read for StdinRaw {
self.0.is_read_vectored() 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> { 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> { 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 { impl Write for StdoutRaw {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 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> { fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
let total = || bufs.iter().map(|b| b.len()).sum(); let total = || Ok(bufs.iter().map(|b| b.len()).sum());
handle_ebadf_lazy(self.0.write_vectored(bufs), total) handle_ebadf(self.0.write_vectored(bufs), total)
} }
#[inline] #[inline]
@ -138,30 +152,30 @@ impl Write for StdoutRaw {
} }
fn flush(&mut self) -> io::Result<()> { 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<()> { 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<()> { 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<()> { 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 { impl Write for StderrRaw {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 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> { fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
let total = || bufs.iter().map(|b| b.len()).sum(); let total = || Ok(bufs.iter().map(|b| b.len()).sum());
handle_ebadf_lazy(self.0.write_vectored(bufs), total) handle_ebadf(self.0.write_vectored(bufs), total)
} }
#[inline] #[inline]
@ -170,32 +184,25 @@ impl Write for StderrRaw {
} }
fn flush(&mut self) -> io::Result<()> { 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<()> { 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<()> { 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<()> { 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(()))
} }
} }
fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> { fn handle_ebadf<T>(r: io::Result<T>, default: impl FnOnce() -> io::Result<T>) -> io::Result<T> {
match r { match r {
Err(ref e) if stdio::is_ebadf(e) => Ok(default), Err(ref e) if stdio::is_ebadf(e) => default(),
r => r,
}
}
fn handle_ebadf_lazy<T>(r: io::Result<T>, default: impl FnOnce() -> T) -> io::Result<T> {
match r {
Err(ref e) if stdio::is_ebadf(e) => Ok(default()),
r => r, r => r,
} }
} }