use crate::errno::Errno;
use crate::Result;
use libc::{self, c_int, c_void, off_t, size_t};
use std::io::{IoSlice, IoSliceMut};
use std::marker::PhantomData;
use std::os::unix::io::RawFd;
pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result<usize> {
let res = unsafe {
libc::writev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
};
Errno::result(res).map(|r| r as usize)
}
pub fn readv(fd: RawFd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
let res = unsafe {
libc::readv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
};
Errno::result(res).map(|r| r as usize)
}
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn pwritev(fd: RawFd, iov: &[IoSlice<'_>], offset: off_t) -> Result<usize> {
#[cfg(target_env = "uclibc")]
let offset = offset as libc::off64_t;
let res = unsafe {
libc::pwritev(
fd,
iov.as_ptr() as *const libc::iovec,
iov.len() as c_int,
offset,
)
};
Errno::result(res).map(|r| r as usize)
}
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn preadv(
fd: RawFd,
iov: &mut [IoSliceMut<'_>],
offset: off_t,
) -> Result<usize> {
#[cfg(target_env = "uclibc")]
let offset = offset as libc::off64_t;
let res = unsafe {
libc::preadv(
fd,
iov.as_ptr() as *const libc::iovec,
iov.len() as c_int,
offset,
)
};
Errno::result(res).map(|r| r as usize)
}
pub fn pwrite(fd: RawFd, buf: &[u8], offset: off_t) -> Result<usize> {
let res = unsafe {
libc::pwrite(
fd,
buf.as_ptr() as *const c_void,
buf.len() as size_t,
offset,
)
};
Errno::result(res).map(|r| r as usize)
}
pub fn pread(fd: RawFd, buf: &mut [u8], offset: off_t) -> Result<usize> {
let res = unsafe {
libc::pread(
fd,
buf.as_mut_ptr() as *mut c_void,
buf.len() as size_t,
offset,
)
};
Errno::result(res).map(|r| r as usize)
}
#[cfg(any(target_os = "linux", target_os = "android"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct RemoteIoVec {
pub base: usize,
pub len: usize,
}
#[deprecated(
since = "0.24.0",
note = "`IoVec` is no longer used in the public interface, use `IoSlice` or `IoSliceMut` instead"
)]
#[repr(transparent)]
#[allow(renamed_and_removed_lints)]
#[allow(clippy::unknown_clippy_lints)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct IoVec<T>(pub(crate) libc::iovec, PhantomData<T>);
#[allow(deprecated)]
impl<T> IoVec<T> {
#[deprecated(
since = "0.24.0",
note = "Use the `Deref` impl of `IoSlice` or `IoSliceMut` instead"
)]
#[inline]
pub fn as_slice(&self) -> &[u8] {
use std::slice;
unsafe {
slice::from_raw_parts(self.0.iov_base as *const u8, self.0.iov_len)
}
}
}
#[allow(deprecated)]
impl<'a> IoVec<&'a [u8]> {
#[deprecated(since = "0.24.0", note = "Use `IoSlice::new` instead")]
pub fn from_slice(buf: &'a [u8]) -> IoVec<&'a [u8]> {
IoVec(
libc::iovec {
iov_base: buf.as_ptr() as *mut c_void,
iov_len: buf.len() as size_t,
},
PhantomData,
)
}
}
#[allow(deprecated)]
impl<'a> IoVec<&'a mut [u8]> {
#[deprecated(since = "0.24.0", note = "Use `IoSliceMut::new` instead")]
pub fn from_mut_slice(buf: &'a mut [u8]) -> IoVec<&'a mut [u8]> {
IoVec(
libc::iovec {
iov_base: buf.as_ptr() as *mut c_void,
iov_len: buf.len() as size_t,
},
PhantomData,
)
}
}
#[allow(deprecated)]
unsafe impl<T> Send for IoVec<T> where T: Send {}
#[allow(deprecated)]
unsafe impl<T> Sync for IoVec<T> where T: Sync {}
feature! {
#![feature = "process"]
#[cfg(all(any(target_os = "linux", target_os = "android"), not(target_env = "uclibc")))]
pub fn process_vm_writev(
pid: crate::unistd::Pid,
local_iov: &[IoSlice<'_>],
remote_iov: &[RemoteIoVec]) -> Result<usize>
{
let res = unsafe {
libc::process_vm_writev(pid.into(),
local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong,
remote_iov.as_ptr() as *const libc::iovec, remote_iov.len() as libc::c_ulong, 0)
};
Errno::result(res).map(|r| r as usize)
}
#[cfg(all(any(target_os = "linux", target_os = "android"), not(target_env = "uclibc")))]
pub fn process_vm_readv(
pid: crate::unistd::Pid,
local_iov: &mut [IoSliceMut<'_>],
remote_iov: &[RemoteIoVec]) -> Result<usize>
{
let res = unsafe {
libc::process_vm_readv(pid.into(),
local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong,
remote_iov.as_ptr() as *const libc::iovec, remote_iov.len() as libc::c_ulong, 0)
};
Errno::result(res).map(|r| r as usize)
}
}