tun_sync/platform/posix/
split.rs1use std::io::{self, Read, Write};
16use std::mem;
17use std::os::unix::io::{AsRawFd, RawFd};
18use std::sync::Arc;
19
20use crate::platform::posix::Fd;
21use libc;
22
23pub struct Reader(pub(crate) Arc<Fd>);
25
26pub struct Writer(pub(crate) Arc<Fd>);
28
29impl Read for Reader {
30 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
31 unsafe {
32 let amount = libc::read(self.0.as_raw_fd(), buf.as_mut_ptr() as *mut _, buf.len());
33
34 if amount < 0 {
35 return Err(io::Error::last_os_error());
36 }
37
38 Ok(amount as usize)
39 }
40 }
41
42 fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
43 unsafe {
44 let mut msg: libc::msghdr = mem::zeroed();
45 msg.msg_iov = bufs.as_mut_ptr().cast();
48 msg.msg_iovlen = bufs.len().min(libc::c_int::MAX as usize) as _;
49
50 let n = libc::recvmsg(self.0.as_raw_fd(), &mut msg, 0);
51 if n < 0 {
52 return Err(io::Error::last_os_error());
53 }
54
55 Ok(n as usize)
56 }
57 }
58}
59
60impl Write for Writer {
61 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
62 unsafe {
63 let amount = libc::write(self.0.as_raw_fd(), buf.as_ptr() as *const _, buf.len());
64
65 if amount < 0 {
66 return Err(io::Error::last_os_error());
67 }
68
69 Ok(amount as usize)
70 }
71 }
72
73 fn flush(&mut self) -> io::Result<()> {
74 Ok(())
75 }
76
77 fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
78 unsafe {
79 let mut msg: libc::msghdr = mem::zeroed();
80 msg.msg_iov = bufs.as_ptr() as *mut _;
83 msg.msg_iovlen = bufs.len().min(libc::c_int::MAX as usize) as _;
84
85 let n = libc::sendmsg(self.0.as_raw_fd(), &msg, 0);
86 if n < 0 {
87 return Err(io::Error::last_os_error());
88 }
89
90 Ok(n as usize)
91 }
92 }
93}
94
95impl AsRawFd for Reader {
96 fn as_raw_fd(&self) -> RawFd {
97 self.0.as_raw_fd()
98 }
99}
100
101impl AsRawFd for Writer {
102 fn as_raw_fd(&self) -> RawFd {
103 self.0.as_raw_fd()
104 }
105}