Skip to content

Commit

Permalink
readv / write for Fd
Browse files Browse the repository at this point in the history
  • Loading branch information
ssrlive committed Jan 22, 2025
1 parent 22e4562 commit 8b625de
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 9 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ all-features = true
crate-type = ["staticlib", "lib"]

[features]
default = []
# default = ["async"]
async = [
"tokio",
Expand Down
2 changes: 1 addition & 1 deletion src/async/unix_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ use tokio::io::Interest;
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
use tokio_util::codec::Framed;

use super::TunPacketCodec;
use crate::device::AbstractDevice;
use crate::platform::posix::{Reader, Writer};
use crate::platform::Device;
use crate::r#async::TunPacketCodec;

/// An async TUN device wrapper around a TUN device.
pub struct AsyncDevice {
Expand Down
2 changes: 1 addition & 1 deletion src/async/win_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.

use super::TunPacketCodec;
use crate::device::AbstractDevice;
use crate::platform::Device;
use crate::r#async::TunPacketCodec;
use core::pin::Pin;
use core::task::{Context, Poll};
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
Expand Down
2 changes: 1 addition & 1 deletion src/platform/android/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::platform::posix::{self, Fd, Tun};

/// A TUN device for Android.
pub struct Device {
tun: Tun,
pub(crate) tun: Tun,
}

impl AsRef<dyn AbstractDevice + 'static> for Device {
Expand Down
2 changes: 1 addition & 1 deletion src/platform/freebsd/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct Route {
/// A TUN device using the TUN/TAP Linux driver.
pub struct Device {
tun_name: String,
tun: Tun,
pub(crate) tun: Tun,
ctl: Fd,
route: Option<Route>,
}
Expand Down
2 changes: 1 addition & 1 deletion src/platform/ios/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use std::{

/// A TUN device for iOS.
pub struct Device {
tun: Tun,
pub(crate) tun: Tun,
}

impl AsRef<dyn AbstractDevice + 'static> for Device {
Expand Down
2 changes: 1 addition & 1 deletion src/platform/linux/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const OVERWRITE_SIZE: usize = std::mem::size_of::<libc::__c_anonymous_ifr_ifru>(
/// A TUN device using the TUN/TAP Linux driver.
pub struct Device {
tun_name: String,
tun: Tun,
pub(crate) tun: Tun,
ctl: Fd,
}

Expand Down
2 changes: 1 addition & 1 deletion src/platform/macos/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ struct Route {
/// A TUN device using the TUN macOS driver.
pub struct Device {
tun_name: Option<String>,
tun: posix::Tun,
pub(crate) tun: posix::Tun,
ctl: Option<posix::Fd>,
route: Option<Route>,
}
Expand Down
2 changes: 1 addition & 1 deletion src/platform/ohos/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::platform::posix::{self, Fd, Tun};

/// A TUN device for OpenHarmony.
pub struct Device {
tun: Tun,
pub(crate) tun: Tun,
}

impl AsRef<dyn AbstractDevice + 'static> for Device {
Expand Down
61 changes: 61 additions & 0 deletions src/platform/posix/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ impl Fd {
}
}

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

#[allow(dead_code)]
#[inline]
fn readv(&self, bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result<usize> {
if bufs.len() > max_iov() {
return Err(std::io::Error::from(std::io::ErrorKind::InvalidInput));
}
let amount = unsafe {
libc::readv(
self.as_raw_fd(),
bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,
bufs.len() as libc::c_int,
)
};
if amount < 0 {
return Err(std::io::Error::last_os_error());
}
Ok(amount as usize)
}

#[inline]
pub fn write(&self, buf: &[u8]) -> std::io::Result<usize> {
let fd = self.as_raw_fd();
let amount = unsafe { libc::write(fd, buf.as_ptr() as *const _, buf.len()) };
Expand All @@ -58,6 +79,25 @@ impl Fd {
}
Ok(amount as usize)
}

#[allow(dead_code)]
#[inline]
pub fn writev(&self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
if bufs.len() > max_iov() {
return Err(std::io::Error::from(std::io::ErrorKind::InvalidInput));
}
let amount = unsafe {
libc::writev(
self.as_raw_fd(),
bufs.as_ptr() as *const libc::iovec,
bufs.len() as libc::c_int,
)
};
if amount < 0 {
return Err(std::io::Error::last_os_error());
}
Ok(amount as usize)
}
}

impl AsRawFd for Fd {
Expand All @@ -81,3 +121,24 @@ impl Drop for Fd {
}
}
}

#[cfg(any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_vendor = "apple",
))]
pub(crate) const fn max_iov() -> usize {
libc::IOV_MAX as usize
}

#[cfg(any(
target_os = "android",
target_os = "emscripten",
target_os = "linux",
target_os = "nto",
))]
pub(crate) const fn max_iov() -> usize {
libc::UIO_MAXIOV as usize
}

0 comments on commit 8b625de

Please sign in to comment.