use crate::errno::Errno;
use crate::Result;
use libc::{self, c_int, off_t, size_t};
use std::io::{IoSlice, IoSliceMut};
use std::os::unix::io::{AsFd, AsRawFd};
pub fn writev<Fd: AsFd>(fd: Fd, iov: &[IoSlice<'_>]) -> Result<usize> {
let res = unsafe {
libc::writev(
fd.as_fd().as_raw_fd(),
iov.as_ptr().cast(),
iov.len() as c_int,
)
};
Errno::result(res).map(|r| r as usize)
}
#[allow(clippy::needless_pass_by_ref_mut)]
pub fn readv<Fd: AsFd>(fd: Fd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
let res = unsafe {
libc::readv(
fd.as_fd().as_raw_fd(),
iov.as_ptr().cast(),
iov.len() as c_int,
)
};
Errno::result(res).map(|r| r as usize)
}
#[cfg(not(any(target_os = "redox", target_os = "haiku", target_os = "solaris", target_os = "cygwin")))]
pub fn pwritev<Fd: AsFd>(
fd: Fd,
iov: &[IoSlice<'_>],
offset: off_t,
) -> Result<usize> {
#[cfg(target_env = "uclibc")]
let offset = offset as libc::off64_t;
let res = unsafe {
libc::pwritev(
fd.as_fd().as_raw_fd(),
iov.as_ptr().cast(),
iov.len() as c_int,
offset,
)
};
Errno::result(res).map(|r| r as usize)
}
#[cfg(not(any(target_os = "redox", target_os = "haiku", target_os = "solaris", target_os = "cygwin")))]
#[allow(clippy::needless_pass_by_ref_mut)]
pub fn preadv<Fd: AsFd>(
fd: Fd,
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.as_fd().as_raw_fd(),
iov.as_ptr().cast(),
iov.len() as c_int,
offset,
)
};
Errno::result(res).map(|r| r as usize)
}
pub fn pwrite<Fd: AsFd>(fd: Fd, buf: &[u8], offset: off_t) -> Result<usize> {
let res = unsafe {
libc::pwrite(
fd.as_fd().as_raw_fd(),
buf.as_ptr().cast(),
buf.len() as size_t,
offset,
)
};
Errno::result(res).map(|r| r as usize)
}
pub fn pread<Fd: AsFd>(fd: Fd, buf: &mut [u8], offset: off_t) -> Result<usize> {
let res = unsafe {
libc::pread(
fd.as_fd().as_raw_fd(),
buf.as_mut_ptr().cast(),
buf.len() as size_t,
offset,
)
};
Errno::result(res).map(|r| r as usize)
}
#[cfg(linux_android)]
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct RemoteIoVec {
pub base: usize,
pub len: usize,
}
feature! {
#![feature = "process"]
#[cfg(all(linux_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().cast(), local_iov.len() as libc::c_ulong,
remote_iov.as_ptr().cast(), remote_iov.len() as libc::c_ulong, 0)
};
Errno::result(res).map(|r| r as usize)
}
#[cfg(all(linux_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().cast(), local_iov.len() as libc::c_ulong,
remote_iov.as_ptr().cast(), remote_iov.len() as libc::c_ulong, 0)
};
Errno::result(res).map(|r| r as usize)
}
}