Trusty: Implement write_vectored for stdio · rust-lang/rust@41b0465 (original) (raw)
1
``
`-
use crate::io;
`
``
1
`+
#[expect(dead_code)]
`
``
2
`+
#[path = "unsupported.rs"]
`
``
3
`+
mod unsupported_stdio;
`
2
4
``
3
``
`-
pub struct Stdin;
`
``
5
`+
use crate::cmp;
`
``
6
`+
use crate::io::{self, IoSlice};
`
``
7
+
``
8
`+
pub type Stdin = unsupported_stdio::Stdin;
`
4
9
`pub struct Stdout;
`
5
10
`pub struct Stderr;
`
6
11
``
7
``
`-
impl Stdin {
`
8
``
`-
pub const fn new() -> Stdin {
`
9
``
`-
Stdin
`
10
``
`-
}
`
11
``
`-
}
`
12
``
-
13
``
`-
impl io::Read for Stdin {
`
14
``
`-
fn read(&mut self, _buf: &mut [u8]) -> io::Result {
`
15
``
`-
Ok(0)
`
16
``
`-
}
`
17
``
`-
}
`
18
``
-
19
12
`impl Stdout {
`
20
13
`pub const fn new() -> Stdout {
`
21
14
`Stdout
`
`@@ -24,7 +17,16 @@ impl Stdout {
`
24
17
``
25
18
`impl io::Write for Stdout {
`
26
19
`fn write(&mut self, buf: &[u8]) -> io::Result {
`
27
``
`-
_write(libc::STDOUT_FILENO, buf)
`
``
20
`+
write(libc::STDOUT_FILENO, buf)
`
``
21
`+
}
`
``
22
+
``
23
`+
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result {
`
``
24
`+
write_vectored(libc::STDOUT_FILENO, bufs)
`
``
25
`+
}
`
``
26
+
``
27
`+
#[inline]
`
``
28
`+
fn is_write_vectored(&self) -> bool {
`
``
29
`+
true
`
28
30
`}
`
29
31
``
30
32
`fn flush(&mut self) -> io::Result<()> {
`
`@@ -40,15 +42,24 @@ impl Stderr {
`
40
42
``
41
43
`impl io::Write for Stderr {
`
42
44
`fn write(&mut self, buf: &[u8]) -> io::Result {
`
43
``
`-
_write(libc::STDERR_FILENO, buf)
`
``
45
`+
write(libc::STDERR_FILENO, buf)
`
``
46
`+
}
`
``
47
+
``
48
`+
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result {
`
``
49
`+
write_vectored(libc::STDERR_FILENO, bufs)
`
``
50
`+
}
`
``
51
+
``
52
`+
#[inline]
`
``
53
`+
fn is_write_vectored(&self) -> bool {
`
``
54
`+
true
`
44
55
`}
`
45
56
``
46
57
`fn flush(&mut self) -> io::Result<()> {
`
47
58
`Ok(())
`
48
59
`}
`
49
60
`}
`
50
61
``
51
``
`-
pub const STDIN_BUF_SIZE: usize = 0;
`
``
62
`+
pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE;
`
52
63
``
53
64
`pub fn is_ebadf(_err: &io::Error) -> bool {
`
54
65
`true
`
`@@ -58,24 +69,24 @@ pub fn panic_output() -> Option {
`
58
69
`Some(Stderr)
`
59
70
`}
`
60
71
``
61
``
`-
fn _write(fd: i32, message: &[u8]) -> io::Result {
`
62
``
`-
let mut iov = libc::iovec { iov_base: message.as_ptr() as *mut _, iov_len: message.len() };
`
63
``
`-
loop {
`
64
``
`-
// SAFETY: syscall, safe arguments.
`
65
``
`-
let ret = unsafe { libc::writev(fd, &iov, 1) };
`
66
``
`-
if ret < 0 {
`
67
``
`-
return Err(io::Error::last_os_error());
`
68
``
`-
}
`
69
``
`-
let ret = ret as usize;
`
70
``
`-
if ret > iov.iov_len {
`
71
``
`-
return Err(io::Error::last_os_error());
`
72
``
`-
}
`
73
``
`-
if ret == iov.iov_len {
`
74
``
`-
return Ok(message.len());
`
75
``
`-
}
`
76
``
`-
// SAFETY: ret has been checked to be less than the length of
`
77
``
`-
// the buffer
`
78
``
`-
iov.iov_base = unsafe { iov.iov_base.add(ret) };
`
79
``
`-
iov.iov_len -= ret;
`
``
72
`+
fn write(fd: i32, buf: &[u8]) -> io::Result {
`
``
73
`+
let iov = libc::iovec { iov_base: buf.as_ptr() as *mut _, iov_len: buf.len() };
`
``
74
`+
// SAFETY: syscall, safe arguments.
`
``
75
`+
let ret = unsafe { libc::writev(fd, &iov, 1) };
`
``
76
`+
// This check includes ret < 0, since the length is at most isize::MAX.
`
``
77
`+
if ret as usize > iov.iov_len {
`
``
78
`+
return Err(io::Error::last_os_error());
`
``
79
`+
}
`
``
80
`+
Ok(ret as usize)
`
``
81
`+
}
`
``
82
+
``
83
`+
fn write_vectored(fd: i32, bufs: &[IoSlice<'_>]) -> io::Result {
`
``
84
`+
let iov = bufs.as_ptr() as *const libc::iovec;
`
``
85
`+
let len = cmp::min(bufs.len(), libc::c_int::MAX as usize) as libc::c_int;
`
``
86
`+
// SAFETY: syscall, safe arguments.
`
``
87
`+
let ret = unsafe { libc::writev(fd, iov, len) };
`
``
88
`+
if ret < 0 {
`
``
89
`+
return Err(io::Error::last_os_error());
`
80
90
`}
`
``
91
`+
Ok(ret as usize)
`
81
92
`}
`