Skip to content

Commit 8b625de

Browse files
committed
readv / write for Fd
1 parent 22e4562 commit 8b625de

File tree

10 files changed

+69
-9
lines changed

10 files changed

+69
-9
lines changed

Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ all-features = true
1616
crate-type = ["staticlib", "lib"]
1717

1818
[features]
19-
default = []
2019
# default = ["async"]
2120
async = [
2221
"tokio",

src/async/unix_device.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ use tokio::io::Interest;
2121
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
2222
use tokio_util::codec::Framed;
2323

24-
use super::TunPacketCodec;
2524
use crate::device::AbstractDevice;
2625
use crate::platform::posix::{Reader, Writer};
2726
use crate::platform::Device;
27+
use crate::r#async::TunPacketCodec;
2828

2929
/// An async TUN device wrapper around a TUN device.
3030
pub struct AsyncDevice {

src/async/win_device.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
//
1313
// 0. You just DO WHAT THE FUCK YOU WANT TO.
1414

15-
use super::TunPacketCodec;
1615
use crate::device::AbstractDevice;
1716
use crate::platform::Device;
17+
use crate::r#async::TunPacketCodec;
1818
use core::pin::Pin;
1919
use core::task::{Context, Poll};
2020
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};

src/platform/android/device.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::platform::posix::{self, Fd, Tun};
2424

2525
/// A TUN device for Android.
2626
pub struct Device {
27-
tun: Tun,
27+
pub(crate) tun: Tun,
2828
}
2929

3030
impl AsRef<dyn AbstractDevice + 'static> for Device {

src/platform/freebsd/device.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct Route {
4343
/// A TUN device using the TUN/TAP Linux driver.
4444
pub struct Device {
4545
tun_name: String,
46-
tun: Tun,
46+
pub(crate) tun: Tun,
4747
ctl: Fd,
4848
route: Option<Route>,
4949
}

src/platform/ios/device.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use std::{
2727

2828
/// A TUN device for iOS.
2929
pub struct Device {
30-
tun: Tun,
30+
pub(crate) tun: Tun,
3131
}
3232

3333
impl AsRef<dyn AbstractDevice + 'static> for Device {

src/platform/linux/device.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const OVERWRITE_SIZE: usize = std::mem::size_of::<libc::__c_anonymous_ifr_ifru>(
3838
/// A TUN device using the TUN/TAP Linux driver.
3939
pub struct Device {
4040
tun_name: String,
41-
tun: Tun,
41+
pub(crate) tun: Tun,
4242
ctl: Fd,
4343
}
4444

src/platform/macos/device.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct Route {
4949
/// A TUN device using the TUN macOS driver.
5050
pub struct Device {
5151
tun_name: Option<String>,
52-
tun: posix::Tun,
52+
pub(crate) tun: posix::Tun,
5353
ctl: Option<posix::Fd>,
5454
route: Option<Route>,
5555
}

src/platform/ohos/device.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::platform::posix::{self, Fd, Tun};
2424

2525
/// A TUN device for OpenHarmony.
2626
pub struct Device {
27-
tun: Tun,
27+
pub(crate) tun: Tun,
2828
}
2929

3030
impl AsRef<dyn AbstractDevice + 'static> for Device {

src/platform/posix/fd.rs

+61
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ impl Fd {
4141
}
4242
}
4343

44+
#[inline]
4445
pub fn read(&self, buf: &mut [u8]) -> std::io::Result<usize> {
4546
let fd = self.as_raw_fd();
4647
let amount = unsafe { libc::read(fd, buf.as_mut_ptr() as *mut _, buf.len()) };
@@ -50,6 +51,26 @@ impl Fd {
5051
Ok(amount as usize)
5152
}
5253

54+
#[allow(dead_code)]
55+
#[inline]
56+
fn readv(&self, bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result<usize> {
57+
if bufs.len() > max_iov() {
58+
return Err(std::io::Error::from(std::io::ErrorKind::InvalidInput));
59+
}
60+
let amount = unsafe {
61+
libc::readv(
62+
self.as_raw_fd(),
63+
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
64+
bufs.len() as libc::c_int,
65+
)
66+
};
67+
if amount < 0 {
68+
return Err(std::io::Error::last_os_error());
69+
}
70+
Ok(amount as usize)
71+
}
72+
73+
#[inline]
5374
pub fn write(&self, buf: &[u8]) -> std::io::Result<usize> {
5475
let fd = self.as_raw_fd();
5576
let amount = unsafe { libc::write(fd, buf.as_ptr() as *const _, buf.len()) };
@@ -58,6 +79,25 @@ impl Fd {
5879
}
5980
Ok(amount as usize)
6081
}
82+
83+
#[allow(dead_code)]
84+
#[inline]
85+
pub fn writev(&self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
86+
if bufs.len() > max_iov() {
87+
return Err(std::io::Error::from(std::io::ErrorKind::InvalidInput));
88+
}
89+
let amount = unsafe {
90+
libc::writev(
91+
self.as_raw_fd(),
92+
bufs.as_ptr() as *const libc::iovec,
93+
bufs.len() as libc::c_int,
94+
)
95+
};
96+
if amount < 0 {
97+
return Err(std::io::Error::last_os_error());
98+
}
99+
Ok(amount as usize)
100+
}
61101
}
62102

63103
impl AsRawFd for Fd {
@@ -81,3 +121,24 @@ impl Drop for Fd {
81121
}
82122
}
83123
}
124+
125+
#[cfg(any(
126+
target_os = "dragonfly",
127+
target_os = "freebsd",
128+
target_os = "netbsd",
129+
target_os = "openbsd",
130+
target_vendor = "apple",
131+
))]
132+
pub(crate) const fn max_iov() -> usize {
133+
libc::IOV_MAX as usize
134+
}
135+
136+
#[cfg(any(
137+
target_os = "android",
138+
target_os = "emscripten",
139+
target_os = "linux",
140+
target_os = "nto",
141+
))]
142+
pub(crate) const fn max_iov() -> usize {
143+
libc::UIO_MAXIOV as usize
144+
}

0 commit comments

Comments
 (0)