Trusty: Implement write_vectored for stdio · rust-lang/rust@41b0465 (original) (raw)

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 {

`

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 {

`

27

``

`-

_write(libc::STDOUT_FILENO, buf)

`

``

20

`+

write(libc::STDOUT_FILENO, buf)

`

``

21

`+

}

`

``

22

+

``

23

`+

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result {

`

``

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 {

`

43

``

`-

_write(libc::STDERR_FILENO, buf)

`

``

45

`+

write(libc::STDERR_FILENO, buf)

`

``

46

`+

}

`

``

47

+

``

48

`+

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result {

`

``

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 {

`

58

69

`Some(Stderr)

`

59

70

`}

`

60

71

``

61

``

`-

fn _write(fd: i32, message: &[u8]) -> io::Result {

`

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 {

`

``

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 {

`

``

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

`}

`