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