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,16 @@ 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
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 < usize > {
43
- _write ( libc:: STDERR_FILENO , buf)
45
+ write ( libc:: STDERR_FILENO , buf)
46
+ }
47
+
48
+ fn write_vectored ( & mut self , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
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<impl io::Write> {
58
69
Some ( Stderr )
59
70
}
60
71
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 ( ) } ;
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 < usize > {
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 < usize > {
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
}
0 commit comments