//! `sys/uio.h` implementation. //! //! See . use core::slice; use crate::{ header::{errno, unistd}, platform::{ self, types::{c_int, c_void, off_t, ssize_t}, }, }; pub use crate::header::bits_iovec::{gather, iovec, scatter}; pub const IOV_MAX: c_int = 1024; /// Non-POSIX, see . #[unsafe(no_mangle)] pub unsafe extern "C" fn preadv( fd: c_int, iov: *const iovec, iovcnt: c_int, offset: off_t, ) -> ssize_t { if !(0..=IOV_MAX).contains(&iovcnt) { platform::ERRNO.set(errno::EINVAL); return -1; } let iovs = unsafe { slice::from_raw_parts(iov, iovcnt as usize) }; let mut vec = unsafe { gather(iovs) }; let ret = unsafe { unistd::pread(fd, vec.as_mut_ptr().cast::(), vec.len(), offset) }; unsafe { scatter(iovs, vec) }; ret } /// Non-POSIX, see . #[unsafe(no_mangle)] pub unsafe extern "C" fn pwritev( fd: c_int, iov: *const iovec, iovcnt: c_int, offset: off_t, ) -> ssize_t { if !(0..=IOV_MAX).contains(&iovcnt) { platform::ERRNO.set(errno::EINVAL); return -1; } let iovs = unsafe { slice::from_raw_parts(iov, iovcnt as usize) }; let vec = unsafe { gather(iovs) }; unsafe { unistd::pwrite(fd, vec.as_ptr().cast::(), vec.len(), offset) } } /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn readv(fd: c_int, iov: *const iovec, iovcnt: c_int) -> ssize_t { if !(0..=IOV_MAX).contains(&iovcnt) { platform::ERRNO.set(errno::EINVAL); return -1; } let iovs = unsafe { slice::from_raw_parts(iov, iovcnt as usize) }; let mut vec = unsafe { gather(iovs) }; let ret = unsafe { unistd::read(fd, vec.as_mut_ptr().cast::(), vec.len()) }; unsafe { scatter(iovs, vec) }; ret } /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn writev(fd: c_int, iov: *const iovec, iovcnt: c_int) -> ssize_t { if !(0..=IOV_MAX).contains(&iovcnt) { platform::ERRNO.set(errno::EINVAL); return -1; } let iovs = unsafe { slice::from_raw_parts(iov, iovcnt as usize) }; let vec = unsafe { gather(iovs) }; unsafe { unistd::write(fd, vec.as_ptr().cast::(), vec.len()) } }