use std::fs::File;
use std::os::unix::io::AsRawFd;
use std::os::unix::net::UnixStream;
use crate::FileReadWriteAtVolatile;
use crate::FileReadWriteVolatile;
pub mod lib {
pub use libc::c_int;
pub use libc::c_void;
pub use libc::iovec;
pub use libc::read;
pub use libc::readv;
pub use libc::size_t;
pub use libc::write;
pub use libc::writev;
}
#[macro_export]
macro_rules! volatile_impl {
($ty:ty) => {
impl FileReadWriteVolatile for $ty {
fn read_volatile(&mut self, slice: $crate::VolatileSlice) -> std::io::Result<usize> {
let ret = unsafe {
$crate::unix::file_traits::lib::read(
self.as_raw_fd(),
slice.as_mut_ptr() as *mut std::ffi::c_void,
slice.size() as usize,
)
};
if ret >= 0 {
Ok(ret as usize)
} else {
Err(std::io::Error::last_os_error())
}
}
fn read_vectored_volatile(
&mut self,
bufs: &[$crate::VolatileSlice],
) -> std::io::Result<usize> {
let iobufs = $crate::VolatileSlice::as_iobufs(bufs);
let iovecs = $crate::IoBufMut::as_iobufs(iobufs);
if iovecs.is_empty() {
return Ok(0);
}
let ret = unsafe {
$crate::unix::file_traits::lib::readv(
self.as_raw_fd(),
iovecs.as_ptr(),
iovecs.len() as std::os::raw::c_int,
)
};
if ret >= 0 {
Ok(ret as usize)
} else {
Err(std::io::Error::last_os_error())
}
}
fn write_volatile(&mut self, slice: $crate::VolatileSlice) -> std::io::Result<usize> {
let ret = unsafe {
$crate::unix::file_traits::lib::write(
self.as_raw_fd(),
slice.as_ptr() as *const std::ffi::c_void,
slice.size() as usize,
)
};
if ret >= 0 {
Ok(ret as usize)
} else {
Err(std::io::Error::last_os_error())
}
}
fn write_vectored_volatile(
&mut self,
bufs: &[$crate::VolatileSlice],
) -> std::io::Result<usize> {
let iobufs = $crate::VolatileSlice::as_iobufs(bufs);
let iovecs = $crate::IoBufMut::as_iobufs(iobufs);
if iovecs.is_empty() {
return Ok(0);
}
let ret = unsafe {
$crate::unix::file_traits::lib::writev(
self.as_raw_fd(),
iovecs.as_ptr(),
iovecs.len() as std::os::raw::c_int,
)
};
if ret >= 0 {
Ok(ret as usize)
} else {
Err(std::io::Error::last_os_error())
}
}
}
};
}
#[macro_export]
macro_rules! volatile_at_impl {
($ty:ty) => {
impl FileReadWriteAtVolatile for $ty {
fn read_at_volatile(
&self,
slice: $crate::VolatileSlice,
offset: u64,
) -> std::io::Result<usize> {
let ret = unsafe {
$crate::platform::pread(
self.as_raw_fd(),
slice.as_mut_ptr() as *mut std::ffi::c_void,
slice.size() as usize,
offset as $crate::platform::off_t,
)
};
if ret >= 0 {
Ok(ret as usize)
} else {
Err(std::io::Error::last_os_error())
}
}
fn read_vectored_at_volatile(
&self,
bufs: &[$crate::VolatileSlice],
offset: u64,
) -> std::io::Result<usize> {
let iobufs = $crate::VolatileSlice::as_iobufs(bufs);
let iovecs = $crate::IoBufMut::as_iobufs(iobufs);
if iovecs.is_empty() {
return Ok(0);
}
let ret = unsafe {
$crate::platform::preadv(
self.as_raw_fd(),
iovecs.as_ptr(),
iovecs.len() as std::os::raw::c_int,
offset as $crate::platform::off_t,
)
};
if ret >= 0 {
Ok(ret as usize)
} else {
Err(std::io::Error::last_os_error())
}
}
fn write_at_volatile(
&self,
slice: $crate::VolatileSlice,
offset: u64,
) -> std::io::Result<usize> {
let ret = unsafe {
$crate::platform::pwrite(
self.as_raw_fd(),
slice.as_ptr() as *const std::ffi::c_void,
slice.size() as usize,
offset as $crate::platform::off_t,
)
};
if ret >= 0 {
Ok(ret as usize)
} else {
Err(std::io::Error::last_os_error())
}
}
fn write_vectored_at_volatile(
&self,
bufs: &[$crate::VolatileSlice],
offset: u64,
) -> std::io::Result<usize> {
let iobufs = $crate::VolatileSlice::as_iobufs(bufs);
let iovecs = $crate::IoBufMut::as_iobufs(iobufs);
if iovecs.is_empty() {
return Ok(0);
}
let ret = unsafe {
$crate::platform::pwritev(
self.as_raw_fd(),
iovecs.as_ptr(),
iovecs.len() as std::os::raw::c_int,
offset as $crate::platform::off_t,
)
};
if ret >= 0 {
Ok(ret as usize)
} else {
Err(std::io::Error::last_os_error())
}
}
}
};
}
volatile_impl!(File);
volatile_at_impl!(File);
volatile_impl!(UnixStream);