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 :: io:: { self , IoSlice } ;
6
+
7
+ pub type Stdin = unsupported_stdio:: Stdin ;
4
8
pub struct Stdout ;
5
9
pub struct Stderr ;
6
10
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 < usize > {
15
- Ok ( 0 )
16
- }
17
- }
18
-
19
11
impl Stdout {
20
12
pub const fn new ( ) -> Stdout {
21
13
Stdout
@@ -24,7 +16,20 @@ impl Stdout {
24
16
25
17
impl io:: Write for Stdout {
26
18
fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
27
- _write ( libc:: STDOUT_FILENO , buf)
19
+ write ( libc:: STDOUT_FILENO , buf)
20
+ }
21
+
22
+ fn write_vectored ( & mut self , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
23
+ write_vectored ( libc:: STDOUT_FILENO , bufs)
24
+ }
25
+
26
+ #[ inline]
27
+ fn is_write_vectored ( & self ) -> bool {
28
+ true
29
+ }
30
+
31
+ fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
32
+ write_all ( libc:: STDOUT_FILENO , buf)
28
33
}
29
34
30
35
fn flush ( & mut self ) -> io:: Result < ( ) > {
@@ -40,15 +45,28 @@ impl Stderr {
40
45
41
46
impl io:: Write for Stderr {
42
47
fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
43
- _write ( libc:: STDERR_FILENO , buf)
48
+ write ( libc:: STDERR_FILENO , buf)
49
+ }
50
+
51
+ fn write_vectored ( & mut self , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
52
+ write_vectored ( libc:: STDERR_FILENO , bufs)
53
+ }
54
+
55
+ #[ inline]
56
+ fn is_write_vectored ( & self ) -> bool {
57
+ true
58
+ }
59
+
60
+ fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
61
+ write_all ( libc:: STDERR_FILENO , buf)
44
62
}
45
63
46
64
fn flush ( & mut self ) -> io:: Result < ( ) > {
47
65
Ok ( ( ) )
48
66
}
49
67
}
50
68
51
- pub const STDIN_BUF_SIZE : usize = 0 ;
69
+ pub const STDIN_BUF_SIZE : usize = unsupported_stdio :: STDIN_BUF_SIZE ;
52
70
53
71
pub fn is_ebadf ( _err : & io:: Error ) -> bool {
54
72
true
@@ -58,20 +76,43 @@ pub fn panic_output() -> Option<impl io::Write> {
58
76
Some ( Stderr )
59
77
}
60
78
61
- fn _write ( fd : i32 , message : & [ u8 ] ) -> io:: Result < usize > {
62
- let mut iov = libc:: iovec { iov_base : message. as_ptr ( ) as * mut _ , iov_len : message. len ( ) } ;
79
+ // FIXME: This should be in libc with a proper value. Several platforms use
80
+ // 1024, but it may not be appropriate for Trusty.
81
+ const IOV_MAX : usize = 1024 ;
82
+
83
+ fn write ( fd : i32 , buf : & [ u8 ] ) -> io:: Result < usize > {
84
+ let iov = libc:: iovec { iov_base : buf. as_ptr ( ) as * mut _ , iov_len : buf. len ( ) } ;
85
+ // SAFETY: syscall, safe arguments.
86
+ let ret = unsafe { libc:: writev ( fd, & iov, 1 ) } ;
87
+ // This check includes ret < 0, since the length is at most isize::MAX.
88
+ if ret as usize > iov. iov_len {
89
+ return Err ( io:: Error :: last_os_error ( ) ) ;
90
+ }
91
+ Ok ( ret as usize )
92
+ }
93
+
94
+ fn write_vectored ( fd : i32 , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
95
+ let iov = bufs. as_ptr ( ) as * const libc:: iovec ;
96
+ // SAFETY: syscall, safe arguments.
97
+ let ret = unsafe { libc:: writev ( fd, iov, bufs. len ( ) . min ( IOV_MAX ) as libc:: c_int ) } ;
98
+ if ret < 0 {
99
+ return Err ( io:: Error :: last_os_error ( ) ) ;
100
+ }
101
+ Ok ( ret as usize )
102
+ }
103
+
104
+ fn write_all ( fd : i32 , buf : & [ u8 ] ) -> io:: Result < ( ) > {
105
+ let mut iov = libc:: iovec { iov_base : buf. as_ptr ( ) as * mut _ , iov_len : buf. len ( ) } ;
63
106
loop {
64
107
// SAFETY: syscall, safe arguments.
65
108
let ret = unsafe { libc:: writev ( fd, & iov, 1 ) } ;
66
- if ret < 0 {
109
+ // This check includes ret < 0, since the length is at most isize::MAX.
110
+ if ret as usize > iov. iov_len {
67
111
return Err ( io:: Error :: last_os_error ( ) ) ;
68
112
}
69
113
let ret = ret as usize ;
70
- if ret > iov. iov_len {
71
- return Err ( io:: Error :: last_os_error ( ) ) ;
72
- }
73
114
if ret == iov. iov_len {
74
- return Ok ( message . len ( ) ) ;
115
+ return Ok ( ( ) ) ;
75
116
}
76
117
// SAFETY: ret has been checked to be less than the length of
77
118
// the buffer
0 commit comments