1- use crate :: io;
1+ #[ expect( dead_code) ]
2+ #[ path = "unsupported.rs" ]
3+ mod unsupported_stdio;
24
3- pub struct Stdin ;
5+ use crate :: cmp;
6+ use crate :: io:: { self , IoSlice } ;
7+
8+ pub type Stdin = unsupported_stdio:: Stdin ;
49pub struct Stdout ;
510pub struct Stderr ;
611
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-
1912impl Stdout {
2013 pub const fn new ( ) -> Stdout {
2114 Stdout
@@ -24,7 +17,16 @@ impl Stdout {
2417
2518impl io:: Write for Stdout {
2619 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
2830 }
2931
3032 fn flush ( & mut self ) -> io:: Result < ( ) > {
@@ -40,15 +42,24 @@ impl Stderr {
4042
4143impl io:: Write for Stderr {
4244 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
4455 }
4556
4657 fn flush ( & mut self ) -> io:: Result < ( ) > {
4758 Ok ( ( ) )
4859 }
4960}
5061
51- pub const STDIN_BUF_SIZE : usize = 0 ;
62+ pub const STDIN_BUF_SIZE : usize = unsupported_stdio :: STDIN_BUF_SIZE ;
5263
5364pub fn is_ebadf ( _err : & io:: Error ) -> bool {
5465 true
@@ -58,24 +69,24 @@ pub fn panic_output() -> Option<impl io::Write> {
5869 Some ( Stderr )
5970}
6071
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 ( ) ) ;
8090 }
91+ Ok ( ret as usize )
8192}
0 commit comments