1- use crate :: io;
1+ #[ expect( dead_code) ]
2+ #[ path = "unsupported.rs" ]
3+ mod unsupported_stdio;
24
3- pub struct Stdin ;
5+ use crate :: io:: { self , IoSlice } ;
6+
7+ pub type Stdin = unsupported_stdio:: Stdin ;
48pub struct Stdout ;
59pub struct Stderr ;
610
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-
1911impl Stdout {
2012 pub const fn new ( ) -> Stdout {
2113 Stdout
@@ -24,7 +16,20 @@ impl Stdout {
2416
2517impl io:: Write for Stdout {
2618 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)
2833 }
2934
3035 fn flush ( & mut self ) -> io:: Result < ( ) > {
@@ -40,15 +45,28 @@ impl Stderr {
4045
4146impl io:: Write for Stderr {
4247 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)
4462 }
4563
4664 fn flush ( & mut self ) -> io:: Result < ( ) > {
4765 Ok ( ( ) )
4866 }
4967}
5068
51- pub const STDIN_BUF_SIZE : usize = 0 ;
69+ pub const STDIN_BUF_SIZE : usize = unsupported_stdio :: STDIN_BUF_SIZE ;
5270
5371pub fn is_ebadf ( _err : & io:: Error ) -> bool {
5472 true
@@ -58,20 +76,43 @@ pub fn panic_output() -> Option<impl io::Write> {
5876 Some ( Stderr )
5977}
6078
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 ( ) } ;
63106 loop {
64107 // SAFETY: syscall, safe arguments.
65108 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 {
67111 return Err ( io:: Error :: last_os_error ( ) ) ;
68112 }
69113 let ret = ret as usize ;
70- if ret > iov. iov_len {
71- return Err ( io:: Error :: last_os_error ( ) ) ;
72- }
73114 if ret == iov. iov_len {
74- return Ok ( message . len ( ) ) ;
115+ return Ok ( ( ) ) ;
75116 }
76117 // SAFETY: ret has been checked to be less than the length of
77118 // the buffer
0 commit comments