Description
Summary
Make using pread
et al nicer by getting rid of a special purpose struct and using a ubiquitous type instead.
Motivation
Using IoVec
in nix is a little cumbersome. At present, in nix, the IoVec
struct is defined:
pub struct IoVec<T> {
iov_base: *mut c_void,
iov_len: size_t,
phantom: PhantomData<T>
}
The C struct iovec
is defined:
struct iovec {
void *iov_base; /* Starting address */
size_t iov_len; /* Number of bytes */
};
This is pretty much equivalent to &[u8]
. See std::raw::Slice
:
pub struct Slice<T> {
pub data: *const T,
pub len: usize,
}
However, the T
type parameter is never used as anything other than [u8]
, and there is no way to even construct one with any other type.
Given that the C struct iovec
is effectively a slice, and that it exists because C lacks slices, I propose we use slices in its place for the Rust interface.
Examples
Signatures before:
pub fn writev(fd: RawFd, iov: &[IoVec<&[u8]>]) -> Result<usize>;
pub fn readv(fd: RawFd, iov: &mut [IoVec<&mut [u8]>]) -> Result<usize>;
After:
pub fn writev(fd: RawFd, iov: &[&[u8]]) -> Result<usize>;
pub fn readv(fd: RawFd, iov: &mut [&mut [u8]]) -> Result<usize>;
If you want to see what it would look like, I've got a partial replacement here: kamalmarhubi@44825ba
The modified tests pass.
Drawbacks
We're relying on a semi-coincidental layout equivalence. This makes me a bit uneasy.
Alternatives
- Leave it as is
- Drop the type parameter, making
IoVec
only store byte slices.