about summary refs log tree commit diff
path: root/library/std/src/sys/stdio
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/sys/stdio')
-rw-r--r--library/std/src/sys/stdio/trusty.rs83
1 files changed, 47 insertions, 36 deletions
diff --git a/library/std/src/sys/stdio/trusty.rs b/library/std/src/sys/stdio/trusty.rs
index d393e95394d..e05461aa44a 100644
--- a/library/std/src/sys/stdio/trusty.rs
+++ b/library/std/src/sys/stdio/trusty.rs
@@ -1,21 +1,14 @@
-use crate::io;
+#[expect(dead_code)]
+#[path = "unsupported.rs"]
+mod unsupported_stdio;
 
-pub struct Stdin;
+use crate::cmp;
+use crate::io::{self, IoSlice};
+
+pub type Stdin = unsupported_stdio::Stdin;
 pub struct Stdout;
 pub struct Stderr;
 
-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
@@ -24,7 +17,16 @@ impl Stdout {
 
 impl io::Write for Stdout {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        _write(libc::STDOUT_FILENO, buf)
+        write(libc::STDOUT_FILENO, buf)
+    }
+
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        write_vectored(libc::STDOUT_FILENO, bufs)
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
     }
 
     fn flush(&mut self) -> io::Result<()> {
@@ -40,7 +42,16 @@ impl Stderr {
 
 impl io::Write for Stderr {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        _write(libc::STDERR_FILENO, buf)
+        write(libc::STDERR_FILENO, buf)
+    }
+
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        write_vectored(libc::STDERR_FILENO, bufs)
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
     }
 
     fn flush(&mut self) -> io::Result<()> {
@@ -48,7 +59,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
@@ -58,24 +69,24 @@ pub fn panic_output() -> Option<impl io::Write> {
     Some(Stderr)
 }
 
-fn _write(fd: i32, message: &[u8]) -> io::Result<usize> {
-    let mut iov = libc::iovec { iov_base: message.as_ptr() as *mut _, iov_len: message.len() };
-    loop {
-        // SAFETY: syscall, safe arguments.
-        let ret = unsafe { libc::writev(fd, &iov, 1) };
-        if ret < 0 {
-            return Err(io::Error::last_os_error());
-        }
-        let ret = ret as usize;
-        if ret > iov.iov_len {
-            return Err(io::Error::last_os_error());
-        }
-        if ret == iov.iov_len {
-            return Ok(message.len());
-        }
-        // SAFETY: ret has been checked to be less than the length of
-        // the buffer
-        iov.iov_base = unsafe { iov.iov_base.add(ret) };
-        iov.iov_len -= ret;
+fn write(fd: i32, buf: &[u8]) -> io::Result<usize> {
+    let iov = libc::iovec { iov_base: buf.as_ptr() as *mut _, iov_len: buf.len() };
+    // SAFETY: syscall, safe arguments.
+    let ret = unsafe { libc::writev(fd, &iov, 1) };
+    // This check includes ret < 0, since the length is at most isize::MAX.
+    if ret as usize > iov.iov_len {
+        return Err(io::Error::last_os_error());
+    }
+    Ok(ret as usize)
+}
+
+fn write_vectored(fd: i32, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+    let iov = bufs.as_ptr() as *const libc::iovec;
+    let len = cmp::min(bufs.len(), libc::c_int::MAX as usize) as libc::c_int;
+    // SAFETY: syscall, safe arguments.
+    let ret = unsafe { libc::writev(fd, iov, len) };
+    if ret < 0 {
+        return Err(io::Error::last_os_error());
     }
+    Ok(ret as usize)
 }