summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--src/fcntl.rs2
-rw-r--r--src/mount/bsd.rs111
-rw-r--r--src/sys/sendfile.rs16
-rw-r--r--src/sys/socket/mod.rs44
-rw-r--r--src/sys/uio.rs163
-rw-r--r--test/sys/test_socket.rs171
-rw-r--r--test/sys/test_uio.rs24
-rw-r--r--test/test_fcntl.rs7
9 files changed, 292 insertions, 248 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f8377ca4..4261670a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -85,6 +85,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
ignoring failures from libc. And getters on the `UtsName` struct now return
an `&OsStr` instead of `&str`.
(#[1672](https://github.com/nix-rust/nix/pull/1672))
+- Replaced `IoVec` with `IoSlice` and `IoSliceMut`, and replaced `IoVec::from_slice` with
+ `IoSlice::new`. (#[1643](https://github.com/nix-rust/nix/pull/1643))
### Fixed
diff --git a/src/fcntl.rs b/src/fcntl.rs
index 6c713608..fa64c8ea 100644
--- a/src/fcntl.rs
+++ b/src/fcntl.rs
@@ -629,7 +629,7 @@ pub fn tee(fd_in: RawFd, fd_out: RawFd, len: usize, flags: SpliceFFlags) -> Resu
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn vmsplice(
fd: RawFd,
- iov: &[crate::sys::uio::IoVec<&[u8]>],
+ iov: &[std::io::IoSlice<'_>],
flags: SpliceFFlags
) -> Result<usize>
{
diff --git a/src/mount/bsd.rs b/src/mount/bsd.rs
index ba0c1a28..b4d611ee 100644
--- a/src/mount/bsd.rs
+++ b/src/mount/bsd.rs
@@ -3,7 +3,6 @@ use crate::{
Errno,
NixPath,
Result,
- sys::uio::IoVec
};
use libc::{c_char, c_int, c_uint, c_void};
use std::{
@@ -11,7 +10,7 @@ use std::{
ffi::{CString, CStr},
fmt,
io,
- ptr
+ marker::PhantomData,
};
@@ -198,13 +197,45 @@ pub type NmountResult = std::result::Result<(), NmountError>;
#[cfg_attr(docsrs, doc(cfg(all())))]
#[derive(Debug, Default)]
pub struct Nmount<'a>{
- iov: Vec<IoVec<&'a [u8]>>,
+ // n.b. notgull: In reality, this is a list that contains
+ // both mutable and immutable pointers.
+ // Be careful using this.
+ iov: Vec<libc::iovec>,
is_owned: Vec<bool>,
+ marker: PhantomData<&'a ()>,
}
#[cfg(target_os = "freebsd")]
#[cfg_attr(docsrs, doc(cfg(all())))]
impl<'a> Nmount<'a> {
+ /// Helper function to push a slice onto the `iov` array.
+ fn push_slice(&mut self, val: &'a [u8], is_owned: bool) {
+ self.iov.push(libc::iovec {
+ iov_base: val.as_ptr() as *mut _,
+ iov_len: val.len(),
+ });
+ self.is_owned.push(is_owned);
+ }
+
+ /// Helper function to push a pointer and its length onto the `iov` array.
+ fn push_pointer_and_length(&mut self, val: *const u8, len: usize, is_owned: bool) {
+ self.iov.push(libc::iovec {
+ iov_base: val as *mut _,
+ iov_len: len,
+ });
+ self.is_owned.push(is_owned);
+ }
+
+ /// Helper function to push a `nix` path as owned.
+ fn push_nix_path<P: ?Sized + NixPath>(&mut self, val: &P) {
+ val.with_nix_path(|s| {
+ let len = s.to_bytes_with_nul().len();
+ let ptr = s.to_owned().into_raw() as *const u8;
+
+ self.push_pointer_and_length(ptr, len, true);
+ }).unwrap();
+ }
+
/// Add an opaque mount option.
///
/// Some file systems take binary-valued mount options. They can be set
@@ -239,10 +270,8 @@ impl<'a> Nmount<'a> {
len: usize
) -> &mut Self
{
- self.iov.push(IoVec::from_slice(name.to_bytes_with_nul()));
- self.is_owned.push(false);
- self.iov.push(IoVec::from_raw_parts(val, len));
- self.is_owned.push(false);
+ self.push_slice(name.to_bytes_with_nul(), false);
+ self.push_pointer_and_length(val.cast(), len, false);
self
}
@@ -258,10 +287,8 @@ impl<'a> Nmount<'a> {
/// .null_opt(&read_only);
/// ```
pub fn null_opt(&mut self, name: &'a CStr) -> &mut Self {
- self.iov.push(IoVec::from_slice(name.to_bytes_with_nul()));
- self.is_owned.push(false);
- self.iov.push(IoVec::from_raw_parts(ptr::null_mut(), 0));
- self.is_owned.push(false);
+ self.push_slice(name.to_bytes_with_nul(), false);
+ self.push_slice(&[], false);
self
}
@@ -283,17 +310,8 @@ impl<'a> Nmount<'a> {
/// ```
pub fn null_opt_owned<P: ?Sized + NixPath>(&mut self, name: &P) -> &mut Self
{
- name.with_nix_path(|s| {
- let len = s.to_bytes_with_nul().len();
- self.iov.push(IoVec::from_raw_parts(
- // Must free it later
- s.to_owned().into_raw() as *mut c_void,
- len
- ));
- self.is_owned.push(true);
- }).unwrap();
- self.iov.push(IoVec::from_raw_parts(ptr::null_mut(), 0));
- self.is_owned.push(false);
+ self.push_nix_path(name);
+ self.push_slice(&[], false);
self
}
@@ -315,10 +333,8 @@ impl<'a> Nmount<'a> {
val: &'a CStr
) -> &mut Self
{
- self.iov.push(IoVec::from_slice(name.to_bytes_with_nul()));
- self.is_owned.push(false);
- self.iov.push(IoVec::from_slice(val.to_bytes_with_nul()));
- self.is_owned.push(false);
+ self.push_slice(name.to_bytes_with_nul(), false);
+ self.push_slice(val.to_bytes_with_nul(), false);
self
}
@@ -341,24 +357,8 @@ impl<'a> Nmount<'a> {
where P1: ?Sized + NixPath,
P2: ?Sized + NixPath
{
- name.with_nix_path(|s| {
- let len = s.to_bytes_with_nul().len();
- self.iov.push(IoVec::from_raw_parts(
- // Must free it later
- s.to_owned().into_raw() as *mut c_void,
- len
- ));
- self.is_owned.push(true);
- }).unwrap();
- val.with_nix_path(|s| {
- let len = s.to_bytes_with_nul().len();
- self.iov.push(IoVec::from_raw_parts(
- // Must free it later
- s.to_owned().into_raw() as *mut c_void,
- len
- ));
- self.is_owned.push(true);
- }).unwrap();
+ self.push_nix_path(name);
+ self.push_nix_path(val);
self
}
@@ -369,18 +369,19 @@ impl<'a> Nmount<'a> {
/// Actually mount the file system.
pub fn nmount(&mut self, flags: MntFlags) -> NmountResult {
- // nmount can return extra error information via a "errmsg" return
- // argument.
const ERRMSG_NAME: &[u8] = b"errmsg\0";
let mut errmsg = vec![0u8; 255];
- self.iov.push(IoVec::from_raw_parts(
- ERRMSG_NAME.as_ptr() as *mut c_void,
- ERRMSG_NAME.len()
- ));
- self.iov.push(IoVec::from_raw_parts(
- errmsg.as_mut_ptr() as *mut c_void,
- errmsg.len()
- ));
+
+ // nmount can return extra error information via a "errmsg" return
+ // argument.
+ self.push_slice(ERRMSG_NAME, false);
+
+ // SAFETY: we are pushing a mutable iovec here, so we can't use
+ // the above method
+ self.iov.push(libc::iovec {
+ iov_base: errmsg.as_mut_ptr() as *mut c_void,
+ iov_len: errmsg.len(),
+ });
let niov = self.iov.len() as c_uint;
let iovp = self.iov.as_mut_ptr() as *mut libc::iovec;
@@ -412,7 +413,7 @@ impl<'a> Drop for Nmount<'a> {
// Free the owned string. Safe because we recorded ownership,
// and Nmount does not implement Clone.
unsafe {
- drop(CString::from_raw(iov.0.iov_base as *mut c_char));
+ drop(CString::from_raw(iov.iov_base as *mut c_char));
}
}
}
diff --git a/src/sys/sendfile.rs b/src/sys/sendfile.rs
index 5ec0b526..2ebcdf48 100644
--- a/src/sys/sendfile.rs
+++ b/src/sys/sendfile.rs
@@ -68,13 +68,13 @@ cfg_if! {
target_os = "freebsd",
target_os = "ios",
target_os = "macos"))] {
- use crate::sys::uio::IoVec;
+ use std::io::IoSlice;
- #[derive(Clone, Debug, Eq, Hash, PartialEq)]
+ #[derive(Clone, Debug)]
struct SendfileHeaderTrailer<'a>(
libc::sf_hdtr,
- Option<Vec<IoVec<&'a [u8]>>>,
- Option<Vec<IoVec<&'a [u8]>>>,
+ Option<Vec<IoSlice<'a>>>,
+ Option<Vec<IoSlice<'a>>>,
);
impl<'a> SendfileHeaderTrailer<'a> {
@@ -82,10 +82,10 @@ cfg_if! {
headers: Option<&'a [&'a [u8]]>,
trailers: Option<&'a [&'a [u8]]>
) -> SendfileHeaderTrailer<'a> {
- let header_iovecs: Option<Vec<IoVec<&[u8]>>> =
- headers.map(|s| s.iter().map(|b| IoVec::from_slice(b)).collect());
- let trailer_iovecs: Option<Vec<IoVec<&[u8]>>> =
- trailers.map(|s| s.iter().map(|b| IoVec::from_slice(b)).collect());
+ let header_iovecs: Option<Vec<IoSlice<'_>>> =
+ headers.map(|s| s.iter().map(|b| IoSlice::new(b)).collect());
+ let trailer_iovecs: Option<Vec<IoSlice<'_>>> =
+ trailers.map(|s| s.iter().map(|b| IoSlice::new(b)).collect());
SendfileHeaderTrailer(
libc::sf_hdtr {
headers: {
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index 8dac6eda..c6613892 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -14,10 +14,8 @@ use std::net;
#[cfg(feature = "uio")]
use crate::sys::time::TimeSpec;
#[cfg(feature = "uio")]
-use crate::sys::{
- time::TimeVal,
- uio::IoVec
-};
+use crate::sys::time::TimeVal;
+use std::io::{IoSlice, IoSliceMut};
#[deny(missing_docs)]
mod addr;
@@ -657,8 +655,8 @@ pub enum ControlMessageOwned {
/// ```
/// # #[macro_use] extern crate nix;
/// # use nix::sys::socket::*;
- /// # use nix::sys::uio::IoVec;
/// # use nix::sys::time::*;
+ /// # use std::io::{IoSlice, IoSliceMut};
/// # use std::time::*;
/// # use std::str::FromStr;
/// # fn main() {
@@ -676,15 +674,15 @@ pub enum ControlMessageOwned {
/// // Get initial time
/// let time0 = SystemTime::now();
/// // Send the message
- /// let iov = [IoVec::from_slice(message)];
+ /// let iov = [IoSlice::new(message)];
/// let flags = MsgFlags::empty();
/// let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
/// assert_eq!(message.len(), l);
/// // Receive the message
/// let mut buffer = vec![0u8; message.len()];
/// let mut cmsgspace = cmsg_space!(TimeVal);
- /// let iov = [IoVec::from_mut_slice(&mut buffer)];
- /// let r = recvmsg::<SockaddrIn>(in_socket, &iov, Some(&mut cmsgspace), flags)
+ /// let mut iov = [IoSliceMut::new(&mut buffer)];
+ /// let r = recvmsg::<SockaddrIn>(in_socket, &mut iov, Some(&mut cmsgspace), flags)
/// .unwrap();
/// let rtime = match r.cmsgs().next() {
/// Some(ControlMessageOwned::ScmTimestamp(rtime)) => rtime,
@@ -1367,13 +1365,13 @@ impl<'a> ControlMessage<'a> {
/// ```
/// # use nix::sys::socket::*;
/// # use nix::unistd::pipe;
-/// # use nix::sys::uio::IoVec;
+/// # use std::io::IoSlice;
/// let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None,
/// SockFlag::empty())
/// .unwrap();
/// let (r, w) = pipe().unwrap();
///
-/// let iov = [IoVec::from_slice(b"hello")];
+/// let iov = [IoSlice::new(b"hello")];
/// let fds = [r];
/// let cmsg = ControlMessage::ScmRights(&fds);
/// sendmsg::<()>(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap();
@@ -1382,19 +1380,19 @@ impl<'a> ControlMessage<'a> {
/// ```
/// # use nix::sys::socket::*;
/// # use nix::unistd::pipe;
-/// # use nix::sys::uio::IoVec;
+/// # use std::io::IoSlice;
/// # use std::str::FromStr;
/// let localhost = SockaddrIn::from_str("1.2.3.4:8080").unwrap();
/// let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(),
/// None).unwrap();
/// let (r, w) = pipe().unwrap();
///
-/// let iov = [IoVec::from_slice(b"hello")];
+/// let iov = [IoSlice::new(b"hello")];
/// let fds = [r];
/// let cmsg = ControlMessage::ScmRights(&fds);
/// sendmsg(fd, &iov, &[cmsg], MsgFlags::empty(), Some(&localhost)).unwrap();
/// ```
-pub fn sendmsg<S>(fd: RawFd, iov: &[IoVec<&[u8]>], cmsgs: &[ControlMessage],
+pub fn sendmsg<S>(fd: RawFd, iov: &[IoSlice<'_>], cmsgs: &[ControlMessage],
flags: MsgFlags, addr: Option<&S>) -> Result<usize>
where S: SockaddrLike
{
@@ -1420,7 +1418,7 @@ pub fn sendmsg<S>(fd: RawFd, iov: &[IoVec<&[u8]>], cmsgs: &[ControlMessage],
#[derive(Debug)]
pub struct SendMmsgData<'a, I, C, S>
where
- I: AsRef<[IoVec<&'a [u8]>]>,
+ I: AsRef<[IoSlice<'a>]>,
C: AsRef<[ControlMessage<'a>]>,
S: SockaddrLike + 'a
{
@@ -1459,7 +1457,7 @@ pub fn sendmmsg<'a, I, C, S>(
flags: MsgFlags
) -> Result<Vec<usize>>
where
- I: AsRef<[IoVec<&'a [u8]>]> + 'a,
+ I: AsRef<[IoSlice<'a>]> + 'a,
C: AsRef<[ControlMessage<'a>]> + 'a,
S: SockaddrLike + 'a
{
@@ -1510,7 +1508,7 @@ pub fn sendmmsg<'a, I, C, S>(
#[derive(Debug)]
pub struct RecvMmsgData<'a, I>
where
- I: AsRef<[IoVec<&'a mut [u8]>]> + 'a,
+ I: AsRef<[IoSliceMut<'a>]> + 'a,
{
pub iov: I,
pub cmsg_buffer: Option<&'a mut Vec<u8>>,
@@ -1557,7 +1555,7 @@ pub fn recvmmsg<'a, I, S>(
timeout: Option<crate::sys::time::TimeSpec>
) -> Result<Vec<RecvMsg<'a, S>>>
where
- I: AsRef<[IoVec<&'a mut [u8]>]> + 'a,
+ I: AsRef<[IoSliceMut<'a>]> + 'a,
S: Copy + SockaddrLike + 'a
{
let iter = data.into_iter();
@@ -1653,14 +1651,14 @@ unsafe fn read_mhdr<'a, 'b, S>(
}
}
-unsafe fn pack_mhdr_to_receive<'a, I, S>(
+unsafe fn pack_mhdr_to_receive<'outer, 'inner, I, S>(
iov: I,
cmsg_buffer: &mut Option<&mut Vec<u8>>,
address: *mut S,
) -> (usize, msghdr)
where
- I: AsRef<[IoVec<&'a mut [u8]>]> + 'a,
- S: SockaddrLike + 'a
+ I: AsRef<[IoSliceMut<'inner>]> + 'outer,
+ S: SockaddrLike + 'outer
{
let (msg_control, msg_controllen) = cmsg_buffer.as_mut()
.map(|v| (v.as_mut_ptr(), v.capacity()))
@@ -1691,7 +1689,7 @@ fn pack_mhdr_to_send<'a, I, C, S>(
addr: Option<&S>
) -> msghdr
where
- I: AsRef<[IoVec<&'a [u8]>]>,
+ I: AsRef<[IoSlice<'a>]>,
C: AsRef<[ControlMessage<'a>]>,
S: SockaddrLike + 'a
{
@@ -1751,7 +1749,7 @@ fn pack_mhdr_to_send<'a, I, C, S>(
///
/// # References
/// [recvmsg(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html)
-pub fn recvmsg<'a, S>(fd: RawFd, iov: &[IoVec<&mut [u8]>],
+pub fn recvmsg<'a, 'outer, 'inner, S>(fd: RawFd, iov: &'outer mut [IoSliceMut<'inner>],
mut cmsg_buffer: Option<&'a mut Vec<u8>>,
flags: MsgFlags) -> Result<RecvMsg<'a, S>>
where S: SockaddrLike + 'a
@@ -1759,7 +1757,7 @@ pub fn recvmsg<'a, S>(fd: RawFd, iov: &[IoVec<&mut [u8]>],
let mut address = mem::MaybeUninit::uninit();
let (msg_controllen, mut mhdr) = unsafe {
- pack_mhdr_to_receive(&iov, &mut cmsg_buffer, address.as_mut_ptr())
+ pack_mhdr_to_receive::<_, S>(iov, &mut cmsg_buffer, address.as_mut_ptr())
};
let ret = unsafe { libc::recvmsg(fd, &mut mhdr, flags.bits()) };
diff --git a/src/sys/uio.rs b/src/sys/uio.rs
index 42298300..ba6c64ef 100644
--- a/src/sys/uio.rs
+++ b/src/sys/uio.rs
@@ -3,13 +3,21 @@
use crate::Result;
use crate::errno::Errno;
use libc::{self, c_int, c_void, size_t, off_t};
+use std::io::{IoSlice, IoSliceMut};
use std::marker::PhantomData;
use std::os::unix::io::RawFd;
/// Low-level vectored write to a raw file descriptor
///
/// See also [writev(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/writev.html)
-pub fn writev(fd: RawFd, iov: &[IoVec<&[u8]>]) -> Result<usize> {
+pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result<usize> {
+ // SAFETY: to quote the documentation for `IoSlice`:
+ //
+ // [IoSlice] is semantically a wrapper around a &[u8], but is
+ // guaranteed to be ABI compatible with the iovec type on Unix
+ // platforms.
+ //
+ // Because it is ABI compatible, a pointer cast here is valid
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)
@@ -18,7 +26,8 @@ pub fn writev(fd: RawFd, iov: &[IoVec<&[u8]>]) -> Result<usize> {
/// Low-level vectored read from a raw file descriptor
///
/// See also [readv(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/readv.html)
-pub fn readv(fd: RawFd, iov: &mut [IoVec<&mut [u8]>]) -> Result<usize> {
+pub fn readv(fd: RawFd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
+ // SAFETY: same as in writev(), IoSliceMut is ABI-compatible with iovec
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)
@@ -32,10 +41,13 @@ pub fn readv(fd: RawFd, iov: &mut [IoVec<&mut [u8]>]) -> Result<usize> {
/// See also: [`writev`](fn.writev.html) and [`pwrite`](fn.pwrite.html)
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn pwritev(fd: RawFd, iov: &[IoVec<&[u8]>],
+pub fn pwritev(fd: RawFd, iov: &[IoSlice<'_>],
offset: off_t) -> Result<usize> {
+
#[cfg(target_env = "uclibc")]
let offset = offset as libc::off64_t; // uclibc doesn't use off_t
+
+ // SAFETY: same as in writev()
let res = unsafe {
libc::pwritev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int, offset)
};
@@ -52,10 +64,12 @@ pub fn pwritev(fd: RawFd, iov: &[IoVec<&[u8]>],
/// See also: [`readv`](fn.readv.html) and [`pread`](fn.pread.html)
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn preadv(fd: RawFd, iov: &[IoVec<&mut [u8]>],
+pub fn preadv(fd: RawFd, iov: &mut [IoSliceMut<'_>],
offset: off_t) -> Result<usize> {
#[cfg(target_env = "uclibc")]
let offset = offset as libc::off64_t; // uclibc doesn't use off_t
+
+ // SAFETY: same as in readv()
let res = unsafe {
libc::preadv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int, offset)
};
@@ -92,9 +106,9 @@ pub fn pread(fd: RawFd, buf: &mut [u8], offset: off_t) -> Result<usize>{
/// A slice of memory in a remote process, starting at address `base`
/// and consisting of `len` bytes.
///
-/// This is the same underlying C structure as [`IoVec`](struct.IoVec.html),
+/// This is the same underlying C structure as `IoSlice`,
/// except that it refers to memory in some other process, and is
-/// therefore not represented in Rust by an actual slice as `IoVec` is. It
+/// therefore not represented in Rust by an actual slice as `IoSlice` is. It
/// is used with [`process_vm_readv`](fn.process_vm_readv.html)
/// and [`process_vm_writev`](fn.process_vm_writev.html).
#[cfg(any(target_os = "linux", target_os = "android"))]
@@ -108,13 +122,82 @@ pub struct RemoteIoVec {
pub len: usize,
}
+/// A vector of buffers.
+///
+/// Vectored I/O methods like [`writev`] and [`readv`] use this structure for
+/// both reading and writing. Each `IoVec` specifies the base address and
+/// length of an area in memory.
+#[deprecated(
+ since = "0.24.0",
+ note = "`IoVec` is no longer used in the public interface, use `IoSlice` or `IoSliceMut` instead"
+)]
+#[repr(transparent)]
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+pub struct IoVec<T>(pub(crate) libc::iovec, PhantomData<T>);
+
+#[allow(deprecated)]
+impl<T> IoVec<T> {
+ /// View the `IoVec` as a Rust slice.
+ #[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 as usize)
+ }
+ }
+}
+
+#[allow(deprecated)]
+impl<'a> IoVec<&'a [u8]> {
+ /// Create an `IoVec` from a Rust slice.
+ #[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]> {
+ /// Create an `IoVec` from a mutable Rust slice.
+ #[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)
+ }
+}
+
+// The only reason IoVec isn't automatically Send+Sync is because libc::iovec
+// contains raw pointers.
+#[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"]
/// Write data directly to another process's virtual memory
/// (see [`process_vm_writev`(2)]).
///
-/// `local_iov` is a list of [`IoVec`]s containing the data to be written,
+/// `local_iov` is a list of [`IoSlice`]s containing the data to be written,
/// and `remote_iov` is a list of [`RemoteIoVec`]s identifying where the
/// data should be written in the target process. On success, returns the
/// number of bytes written, which will always be a whole
@@ -129,12 +212,12 @@ feature! {
///
/// [`process_vm_writev`(2)]: https://man7.org/linux/man-pages/man2/process_vm_writev.2.html
/// [ptrace]: ../ptrace/index.html
-/// [`IoVec`]: struct.IoVec.html
+/// [`IoSlice`]: https://doc.rust-lang.org/std/io/struct.IoSlice.html
/// [`RemoteIoVec`]: struct.RemoteIoVec.html
#[cfg(all(any(target_os = "linux", target_os = "android"), not(target_env = "uclibc")))]
pub fn process_vm_writev(
pid: crate::unistd::Pid,
- local_iov: &[IoVec<&[u8]>],
+ local_iov: &[IoSlice<'_>],
remote_iov: &[RemoteIoVec]) -> Result<usize>
{
let res = unsafe {
@@ -149,7 +232,7 @@ pub fn process_vm_writev(
/// Read data directly from another process's virtual memory
/// (see [`process_vm_readv`(2)]).
///
-/// `local_iov` is a list of [`IoVec`]s containing the buffer to copy
+/// `local_iov` is a list of [`IoSliceMut`]s containing the buffer to copy
/// data into, and `remote_iov` is a list of [`RemoteIoVec`]s identifying
/// where the source data is in the target process. On success,
/// returns the number of bytes written, which will always be a whole
@@ -164,12 +247,12 @@ pub fn process_vm_writev(
///
/// [`process_vm_readv`(2)]: https://man7.org/linux/man-pages/man2/process_vm_readv.2.html
/// [`ptrace`]: ../ptrace/index.html
-/// [`IoVec`]: struct.IoVec.html
+/// [`IoSliceMut`]: https://doc.rust-lang.org/std/io/struct.IoSliceMut.html
/// [`RemoteIoVec`]: struct.RemoteIoVec.html
#[cfg(all(any(target_os = "linux", target_os = "android"), not(target_env = "uclibc")))]
pub fn process_vm_readv(
pid: crate::unistd::Pid,
- local_iov: &[IoVec<&mut [u8]>],
+ local_iov: &mut [IoSliceMut<'_>],
remote_iov: &[RemoteIoVec]) -> Result<usize>
{
let res = unsafe {
@@ -181,59 +264,3 @@ pub fn process_vm_readv(
Errno::result(res).map(|r| r as usize)
}
}
-
-/// A vector of buffers.
-///
-/// Vectored I/O methods like [`writev`] and [`readv`] use this structure for
-/// both reading and writing. Each `IoVec` specifies the base address and
-/// length of an area in memory.
-#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct IoVec<T>(pub(crate) libc::iovec, PhantomData<T>);
-
-impl<T> IoVec<T> {
- /// View the `IoVec` as a Rust slice.
- #[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 as usize)
- }
- }
-}
-
-impl<'a> IoVec<&'a [u8]> {
- #[cfg(all(feature = "mount", target_os = "freebsd"))]
- pub(crate) fn from_raw_parts(base: *mut c_void, len: usize) -> Self {
- IoVec(libc::iovec {
- iov_base: base,
- iov_len: len
- }, PhantomData)
- }
-
- /// Create an `IoVec` from a Rust slice.
- 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)
- }
-}
-
-impl<'a> IoVec<&'a mut [u8]> {
- /// Create an `IoVec` from a mutable Rust slice.
- 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)
- }
-}
-
-// The only reason IoVec isn't automatically Send+Sync is because libc::iovec
-// contains raw pointers.
-unsafe impl<T> Send for IoVec<T> where T: Send {}
-unsafe impl<T> Sync for IoVec<T> where T: Sync {}
diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs
index c18442fd..2aac7958 100644
--- a/test/sys/test_socket.rs
+++ b/test/sys/test_socket.rs
@@ -72,7 +72,7 @@ pub fn test_timestamping() {
recvmsg, sendmsg, setsockopt, socket, sockopt::Timestamping, ControlMessageOwned, MsgFlags,
SockaddrIn, SockFlag, SockType, TimestampingFlag,
};
- use nix::sys::uio::IoVec;
+ use std::io::{IoSlice, IoSliceMut};
let sock_addr = SockaddrIn::from_str("127.0.0.1:6790").unwrap();
@@ -98,11 +98,12 @@ pub fn test_timestamping() {
let sbuf = [0u8; 2048];
let mut rbuf = [0u8; 2048];
let flags = MsgFlags::empty();
- let iov1 = [IoVec::from_slice(&sbuf)];
- let iov2 = [IoVec::from_mut_slice(&mut rbuf)];
+ let iov1 = [IoSlice::new(&sbuf)];
+ let mut iov2 = [IoSliceMut::new(&mut rbuf)];
+
let mut cmsg = cmsg_space!(nix::sys::socket::Timestamps);
sendmsg(ssock, &iov1, &[], flags, Some(&sock_addr)).unwrap();
- let recv = recvmsg::<()>(rsock, &iov2, Some(&mut cmsg), flags).unwrap();
+ let recv = recvmsg::<()>(rsock, &mut iov2, Some(&mut cmsg), flags).unwrap();
let mut ts = None;
for c in recv.cmsgs() {
@@ -327,8 +328,8 @@ mod recvfrom {
#[cfg(target_os = "linux")]
mod udp_offload {
use super::*;
- use nix::sys::uio::IoVec;
use nix::sys::socket::sockopt::{UdpGroSegment, UdpGsoSegment};
+ use std::io::IoSlice;
#[test]
// Disable the test under emulation because it fails in Cirrus-CI. Lack
@@ -363,7 +364,7 @@ mod recvfrom {
let mut num_packets_received: i32 = 0;
sendrecv(rsock, ssock, move |s, m, flags| {
- let iov = [IoVec::from_slice(m)];
+ let iov = [IoSlice::new(m)];
let cmsg = ControlMessage::UdpGsoSegments(&segment_size);
sendmsg(s, &iov, &[cmsg], flags, Some(&sock_addr))
}, {
@@ -411,7 +412,7 @@ mod recvfrom {
))]
#[test]
pub fn udp_sendmmsg() {
- use nix::sys::uio::IoVec;
+ use std::io::IoSlice;
let std_sa = SocketAddrV4::from_str("127.0.0.1:6793").unwrap();
let std_sa2 = SocketAddrV4::from_str("127.0.0.1:6794").unwrap();
@@ -432,7 +433,7 @@ mod recvfrom {
).expect("send socket failed");
let from = sendrecv(rsock, ssock, move |s, m, flags| {
- let iov = [IoVec::from_slice(m)];
+ let iov = [IoSlice::new(m)];
let mut msgs = vec![
SendMmsgData {
iov: &iov,
@@ -475,7 +476,7 @@ mod recvfrom {
))]
#[test]
pub fn udp_recvmmsg() {
- use nix::sys::uio::IoVec;
+ use std::io::IoSliceMut;
use nix::sys::socket::{MsgFlags, recvmmsg};
const NUM_MESSAGES_SENT: usize = 2;
@@ -508,7 +509,7 @@ mod recvfrom {
// Buffers to receive exactly `NUM_MESSAGES_SENT` messages
let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT];
let iovs: Vec<_> = receive_buffers.iter_mut().map(|buf| {
- [IoVec::from_mut_slice(&mut buf[..])]
+ [IoSliceMut::new(&mut buf[..])]
}).collect();
for iov in &iovs {
@@ -541,8 +542,8 @@ mod recvfrom {
))]
#[test]
pub fn udp_recvmmsg_dontwait_short_read() {
- use nix::sys::uio::IoVec;
use nix::sys::socket::{MsgFlags, recvmmsg};
+ use std::io::IoSliceMut;
const NUM_MESSAGES_SENT: usize = 2;
const DATA: [u8; 4] = [1,2,3,4];
@@ -579,7 +580,7 @@ mod recvfrom {
// kernel buffers when using `MSG_DONTWAIT`.
let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT + 2];
let iovs: Vec<_> = receive_buffers.iter_mut().map(|buf| {
- [IoVec::from_mut_slice(&mut buf[..])]
+ [IoSliceMut::new(&mut buf[..])]
}).collect();
for iov in &iovs {
@@ -608,12 +609,14 @@ mod recvfrom {
pub fn test_recvmsg_ebadf() {
use nix::errno::Errno;
use nix::sys::socket::{MsgFlags, recvmsg};
- use nix::sys::uio::IoVec;
+ use std::io::IoSliceMut;
let mut buf = [0u8; 5];
- let iov = [IoVec::from_mut_slice(&mut buf[..])];
+ let mut iov = [IoSliceMut::new(&mut buf[..])];
+
let fd = -1; // Bad file descriptor
- let r = recvmsg::<()>(fd, &iov, None, MsgFlags::empty());
+ let r = recvmsg::<()>(fd, &mut iov, None, MsgFlags::empty());
+
assert_eq!(r.err().unwrap(), Errno::EBADF);
}
@@ -622,11 +625,11 @@ pub fn test_recvmsg_ebadf() {
#[cfg_attr(qemu, ignore)]
#[test]
pub fn test_scm_rights() {
- use nix::sys::uio::IoVec;
use nix::unistd::{pipe, read, write, close};
use nix::sys::socket::{socketpair, sendmsg, recvmsg,
AddressFamily, SockType, SockFlag,
ControlMessage, ControlMessageOwned, MsgFlags};
+ use std::io::{IoSlice, IoSliceMut};
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
.unwrap();
@@ -634,7 +637,7 @@ pub fn test_scm_rights() {
let mut received_r: Option<RawFd> = None;
{
- let iov = [IoVec::from_slice(b"hello")];
+ let iov = [IoSlice::new(b"hello")];
let fds = [r];
let cmsg = ControlMessage::ScmRights(&fds);
assert_eq!(sendmsg::<()>(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(), 5);
@@ -644,9 +647,10 @@ pub fn test_scm_rights() {
{
let mut buf = [0u8; 5];
- let iov = [IoVec::from_mut_slice(&mut buf[..])];
+
+ let mut iov = [IoSliceMut::new(&mut buf[..])];
let mut cmsgspace = cmsg_space!([RawFd; 1]);
- let msg = recvmsg::<()>(fd2, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
+ let msg = recvmsg::<()>(fd2, &mut iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
for cmsg in msg.cmsgs() {
if let ControlMessageOwned::ScmRights(fd) = cmsg {
@@ -677,12 +681,12 @@ pub fn test_scm_rights() {
#[cfg_attr(qemu, ignore)]
#[test]
pub fn test_af_alg_cipher() {
- use nix::sys::uio::IoVec;
use nix::unistd::read;
use nix::sys::socket::{socket, sendmsg, bind, accept, setsockopt,
AddressFamily, SockType, SockFlag, AlgAddr,
ControlMessage, MsgFlags};
use nix::sys::socket::sockopt::AlgSetKey;
+ use std::io::IoSlice;
skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1352");
// Travis's seccomp profile blocks AF_ALG
@@ -713,7 +717,7 @@ pub fn test_af_alg_cipher() {
let session_socket = accept(sock).expect("accept failed");
let msgs = [ControlMessage::AlgSetOp(&libc::ALG_OP_ENCRYPT), ControlMessage::AlgSetIv(iv.as_slice())];
- let iov = IoVec::from_slice(&payload);
+ let iov = IoSlice::new(&payload);
sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None).expect("sendmsg encrypt");
// allocate buffer for encrypted data
@@ -721,7 +725,7 @@ pub fn test_af_alg_cipher() {
let num_bytes = read(session_socket, &mut encrypted).expect("read encrypt");
assert_eq!(num_bytes, payload_len);
- let iov = IoVec::from_slice(&encrypted);
+ let iov = IoSlice::new(&encrypted);
let iv = vec![1u8; iv_len];
@@ -744,12 +748,12 @@ pub fn test_af_alg_cipher() {
pub fn test_af_alg_aead() {
use libc::{ALG_OP_DECRYPT, ALG_OP_ENCRYPT};
use nix::fcntl::{fcntl, FcntlArg, OFlag};
- use nix::sys::uio::IoVec;
use nix::unistd::{read, close};
use nix::sys::socket::{socket, sendmsg, bind, accept, setsockopt,
AddressFamily, SockType, SockFlag, AlgAddr,
ControlMessage, MsgFlags};
use nix::sys::socket::sockopt::{AlgSetKey, AlgSetAeadAuthSize};
+ use std::io::IoSlice;
skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1352");
// Travis's seccomp profile blocks AF_ALG
@@ -794,7 +798,8 @@ pub fn test_af_alg_aead() {
ControlMessage::AlgSetOp(&ALG_OP_ENCRYPT),
ControlMessage::AlgSetIv(iv.as_slice()),
ControlMessage::AlgSetAeadAssoclen(&assoc_size)];
- let iov = IoVec::from_slice(&payload);
+
+ let iov = IoSlice::new(&payload);
sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None).expect("sendmsg encrypt");
// allocate buffer for encrypted data
@@ -807,7 +812,7 @@ pub fn test_af_alg_aead() {
encrypted[i as usize] = 10;
}
- let iov = IoVec::from_slice(&encrypted);
+ let iov = IoSlice::new(&encrypted);
let iv = vec![1u8; iv_len];
@@ -846,10 +851,10 @@ pub fn test_af_alg_aead() {
#[test]
pub fn test_sendmsg_ipv4packetinfo() {
use cfg_if::cfg_if;
- use nix::sys::uio::IoVec;
use nix::sys::socket::{socket, sendmsg, bind,
AddressFamily, SockType, SockFlag, SockaddrIn,
ControlMessage, MsgFlags};
+ use std::io::IoSlice;
let sock = socket(AddressFamily::Inet,
SockType::Datagram,
@@ -862,7 +867,7 @@ pub fn test_sendmsg_ipv4packetinfo() {
bind(sock, &sock_addr).expect("bind failed");
let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoVec::from_slice(&slice)];
+ let iov = [IoSlice::new(&slice)];
cfg_if! {
if #[cfg(target_os = "netbsd")] {
@@ -900,10 +905,10 @@ pub fn test_sendmsg_ipv4packetinfo() {
#[test]
pub fn test_sendmsg_ipv6packetinfo() {
use nix::errno::Errno;
- use nix::sys::uio::IoVec;
use nix::sys::socket::{socket, sendmsg, bind,
AddressFamily, SockType, SockFlag, SockaddrIn6,
ControlMessage, MsgFlags};
+ use std::io::IoSlice;
let sock = socket(AddressFamily::Inet6,
SockType::Datagram,
@@ -920,7 +925,7 @@ pub fn test_sendmsg_ipv6packetinfo() {
}
let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoVec::from_slice(&slice)];
+ let iov = [IoSlice::new(&slice)];
let pi = libc::in6_pktinfo {
ipi6_ifindex: 0, /* Unspecified interface */
@@ -944,16 +949,17 @@ fn test_scm_rights_single_cmsg_multiple_fds() {
use std::thread;
use nix::sys::socket::{ControlMessage, ControlMessageOwned, MsgFlags,
sendmsg, recvmsg};
- use nix::sys::uio::IoVec;
+ use std::io::{IoSlice, IoSliceMut};
let (send, receive) = UnixDatagram::pair().unwrap();
let thread = thread::spawn(move || {
let mut buf = [0u8; 8];
- let iovec = [IoVec::from_mut_slice(&mut buf)];
+ let mut iovec = [IoSliceMut::new(&mut buf)];
+
let mut space = cmsg_space!([RawFd; 2]);
let msg = recvmsg::<()>(
receive.as_raw_fd(),
- &iovec,
+ &mut iovec,
Some(&mut space),
MsgFlags::empty()
).unwrap();
@@ -971,11 +977,11 @@ fn test_scm_rights_single_cmsg_multiple_fds() {
assert!(cmsgs.next().is_none(), "unexpected control msg");
assert_eq!(msg.bytes, 8);
- assert_eq!(iovec[0].as_slice(), [1u8, 2, 3, 4, 5, 6, 7, 8]);
+ assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
});
let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoVec::from_slice(&slice)];
+ let iov = [IoSlice::new(&slice)];
let fds = [libc::STDIN_FILENO, libc::STDOUT_FILENO]; // pass stdin and stdout
let cmsg = [ControlMessage::ScmRights(&fds)];
sendmsg::<()>(send.as_raw_fd(), &iov, &cmsg, MsgFlags::empty(), None).unwrap();
@@ -988,25 +994,26 @@ fn test_scm_rights_single_cmsg_multiple_fds() {
// raw `sendmsg`.
#[test]
pub fn test_sendmsg_empty_cmsgs() {
- use nix::sys::uio::IoVec;
use nix::unistd::close;
use nix::sys::socket::{socketpair, sendmsg, recvmsg,
AddressFamily, SockType, SockFlag, MsgFlags};
+ use std::io::{IoSlice, IoSliceMut};
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
.unwrap();
{
- let iov = [IoVec::from_slice(b"hello")];
+ let iov = [IoSlice::new(b"hello")];
assert_eq!(sendmsg::<()>(fd1, &iov, &[], MsgFlags::empty(), None).unwrap(), 5);
close(fd1).unwrap();
}
{
let mut buf = [0u8; 5];
- let iov = [IoVec::from_mut_slice(&mut buf[..])];
+ let mut iov = [IoSliceMut::new(&mut buf[..])];
+
let mut cmsgspace = cmsg_space!([RawFd; 1]);
- let msg = recvmsg::<()>(fd2, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
+ let msg = recvmsg::<()>(fd2, &mut iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
for _ in msg.cmsgs() {
panic!("unexpected cmsg");
@@ -1025,7 +1032,6 @@ pub fn test_sendmsg_empty_cmsgs() {
))]
#[test]
fn test_scm_credentials() {
- use nix::sys::uio::IoVec;
use nix::unistd::{close, getpid, getuid, getgid};
use nix::sys::socket::{socketpair, sendmsg, recvmsg,
AddressFamily, SockType, SockFlag,
@@ -1033,6 +1039,7 @@ fn test_scm_credentials() {
UnixCredentials};
#[cfg(any(target_os = "android", target_os = "linux"))]
use nix::sys::socket::{setsockopt, sockopt::PassCred};
+ use std::io::{IoSlice, IoSliceMut};
let (send, recv) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
.unwrap();
@@ -1040,7 +1047,7 @@ fn test_scm_credentials() {
setsockopt(recv, PassCred, &true).unwrap();
{
- let iov = [IoVec::from_slice(b"hello")];
+ let iov = [IoSlice::new(b"hello")];
#[cfg(any(target_os = "android", target_os = "linux"))]
let cred = UnixCredentials::new();
#[cfg(any(target_os = "android", target_os = "linux"))]
@@ -1053,9 +1060,10 @@ fn test_scm_credentials() {
{
let mut buf = [0u8; 5];
- let iov = [IoVec::from_mut_slice(&mut buf[..])];
+ let mut iov = [IoSliceMut::new(&mut buf[..])];
+
let mut cmsgspace = cmsg_space!(UnixCredentials);
- let msg = recvmsg::<()>(recv, &iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
+ let msg = recvmsg::<()>(recv, &mut iov, Some(&mut cmsgspace), MsgFlags::empty()).unwrap();
let mut received_cred = None;
for cmsg in msg.cmsgs() {
@@ -1106,12 +1114,12 @@ fn test_too_large_cmsgspace() {
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_impl_scm_credentials_and_rights(mut space: Vec<u8>) {
use libc::ucred;
- use nix::sys::uio::IoVec;
use nix::unistd::{pipe, write, close, getpid, getuid, getgid};
use nix::sys::socket::{socketpair, sendmsg, recvmsg, setsockopt,
SockType, SockFlag,
ControlMessage, ControlMessageOwned, MsgFlags};
use nix::sys::socket::sockopt::PassCred;
+ use std::io::{IoSlice, IoSliceMut};
let (send, recv) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
.unwrap();
@@ -1121,7 +1129,7 @@ fn test_impl_scm_credentials_and_rights(mut space: Vec<u8>) {
let mut received_r: Option<RawFd> = None;
{
- let iov = [IoVec::from_slice(b"hello")];
+ let iov = [IoSlice::new(b"hello")];
let cred = ucred {
pid: getpid().as_raw(),
uid: getuid().as_raw(),
@@ -1139,8 +1147,8 @@ fn test_impl_scm_credentials_and_rights(mut space: Vec<u8>) {
{
let mut buf = [0u8; 5];
- let iov = [IoVec::from_mut_slice(&mut buf[..])];
- let msg = recvmsg::<()>(recv, &iov, Some(&mut space), MsgFlags::empty()).unwrap();
+ let mut iov = [IoSliceMut::new(&mut buf[..])];
+ let msg = recvmsg::<()>(recv, &mut iov, Some(&mut space), MsgFlags::empty()).unwrap();
let mut received_cred = None;
assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs");
@@ -1289,8 +1297,8 @@ pub fn test_recv_ipv4pktinfo() {
use nix::sys::socket::{bind, SockaddrIn, SockFlag, SockType};
use nix::sys::socket::{getsockname, setsockopt, socket};
use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use nix::sys::uio::IoVec;
use nix::net::if_::*;
+ use std::io::{IoSlice, IoSliceMut};
let lo_ifaddr = loopback_address(AddressFamily::Inet);
let (lo_name, lo) = match lo_ifaddr {
@@ -1310,7 +1318,7 @@ pub fn test_recv_ipv4pktinfo() {
{
let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoVec::from_slice(&slice)];
+ let iov = [IoSlice::new(&slice)];
let send = socket(
AddressFamily::Inet,
@@ -1323,11 +1331,12 @@ pub fn test_recv_ipv4pktinfo() {
{
let mut buf = [0u8; 8];
- let iovec = [IoVec::from_mut_slice(&mut buf)];
+ let mut iovec = [IoSliceMut::new(&mut buf)];
+
let mut space = cmsg_space!(libc::in_pktinfo);
let msg = recvmsg::<()>(
receive,
- &iovec,
+ &mut iovec,
Some(&mut space),
MsgFlags::empty(),
).expect("recvmsg failed");
@@ -1350,7 +1359,7 @@ pub fn test_recv_ipv4pktinfo() {
assert!(cmsgs.next().is_none(), "unexpected additional control msg");
assert_eq!(msg.bytes, 8);
assert_eq!(
- iovec[0].as_slice(),
+ *iovec[0],
[1u8, 2, 3, 4, 5, 6, 7, 8]
);
}
@@ -1379,7 +1388,7 @@ pub fn test_recvif() {
use nix::sys::socket::{bind, SockaddrIn, SockFlag, SockType};
use nix::sys::socket::{getsockname, setsockopt, socket};
use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use nix::sys::uio::IoVec;
+ use std::io::{IoSlice, IoSliceMut};
let lo_ifaddr = loopback_address(AddressFamily::Inet);
let (lo_name, lo) = match lo_ifaddr {
@@ -1400,7 +1409,7 @@ pub fn test_recvif() {
{
let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoVec::from_slice(&slice)];
+ let iov = [IoSlice::new(&slice)];
let send = socket(
AddressFamily::Inet,
@@ -1413,11 +1422,11 @@ pub fn test_recvif() {
{
let mut buf = [0u8; 8];
- let iovec = [IoVec::from_mut_slice(&mut buf)];
+ let mut iovec = [IoSliceMut::new(&mut buf)];
let mut space = cmsg_space!(libc::sockaddr_dl, libc::in_addr);
let msg = recvmsg::<()>(
receive,
- &iovec,
+ &mut iovec,
Some(&mut space),
MsgFlags::empty(),
).expect("recvmsg failed");
@@ -1461,7 +1470,7 @@ pub fn test_recvif() {
assert!(rx_recvdstaddr);
assert_eq!(msg.bytes, 8);
assert_eq!(
- iovec[0].as_slice(),
+ *iovec[0],
[1u8, 2, 3, 4, 5, 6, 7, 8]
);
}
@@ -1492,7 +1501,7 @@ pub fn test_recv_ipv6pktinfo() {
use nix::sys::socket::{bind, SockaddrIn6, SockFlag, SockType};
use nix::sys::socket::{getsockname, setsockopt, socket};
use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use nix::sys::uio::IoVec;
+ use std::io::{IoSlice, IoSliceMut};
let lo_ifaddr = loopback_address(AddressFamily::Inet6);
let (lo_name, lo) = match lo_ifaddr {
@@ -1512,7 +1521,7 @@ pub fn test_recv_ipv6pktinfo() {
{
let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoVec::from_slice(&slice)];
+ let iov = [IoSlice::new(&slice)];
let send = socket(
AddressFamily::Inet6,
@@ -1525,11 +1534,12 @@ pub fn test_recv_ipv6pktinfo() {
{
let mut buf = [0u8; 8];
- let iovec = [IoVec::from_mut_slice(&mut buf)];
+ let mut iovec = [IoSliceMut::new(&mut buf)];
+
let mut space = cmsg_space!(libc::in6_pktinfo);
let msg = recvmsg::<()>(
receive,
- &iovec,
+ &mut iovec,
Some(&mut space),
MsgFlags::empty(),
).expect("recvmsg failed");
@@ -1553,7 +1563,7 @@ pub fn test_recv_ipv6pktinfo() {
assert!(cmsgs.next().is_none(), "unexpected additional control msg");
assert_eq!(msg.bytes, 8);
assert_eq!(
- iovec[0].as_slice(),
+ *iovec[0],
[1u8, 2, 3, 4, 5, 6, 7, 8]
);
}
@@ -1611,7 +1621,7 @@ pub fn test_vsock() {
#[test]
fn test_recvmsg_timestampns() {
use nix::sys::socket::*;
- use nix::sys::uio::IoVec;
+ use std::io::{IoSlice, IoSliceMut};
use nix::sys::time::*;
use std::time::*;
@@ -1629,15 +1639,16 @@ fn test_recvmsg_timestampns() {
// Get initial time
let time0 = SystemTime::now();
// Send the message
- let iov = [IoVec::from_slice(message)];
+ let iov = [IoSlice::new(message)];
let flags = MsgFlags::empty();
let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
assert_eq!(message.len(), l);
// Receive the message
let mut buffer = vec![0u8; message.len()];
let mut cmsgspace = nix::cmsg_space!(TimeSpec);
- let iov = [IoVec::from_mut_slice(&mut buffer)];
- let r = recvmsg::<()>(in_socket, &iov, Some(&mut cmsgspace), flags).unwrap();
+
+ let mut iov = [IoSliceMut::new(&mut buffer)];
+ let r = recvmsg::<()>(in_socket, &mut iov, Some(&mut cmsgspace), flags).unwrap();
let rtime = match r.cmsgs().next() {
Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime,
Some(_) => panic!("Unexpected control message"),
@@ -1662,7 +1673,7 @@ fn test_recvmsg_timestampns() {
#[test]
fn test_recvmmsg_timestampns() {
use nix::sys::socket::*;
- use nix::sys::uio::IoVec;
+ use std::io::{IoSlice, IoSliceMut};
use nix::sys::time::*;
use std::time::*;
@@ -1680,14 +1691,14 @@ fn test_recvmmsg_timestampns() {
// Get initial time
let time0 = SystemTime::now();
// Send the message
- let iov = [IoVec::from_slice(message)];
+ let iov = [IoSlice::new(message)];
let flags = MsgFlags::empty();
let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
assert_eq!(message.len(), l);
// Receive the message
let mut buffer = vec![0u8; message.len()];
let mut cmsgspace = nix::cmsg_space!(TimeSpec);
- let iov = [IoVec::from_mut_slice(&mut buffer)];
+ let iov = [IoSliceMut::new(&mut buffer)];
let mut data = vec![
RecvMmsgData {
iov,
@@ -1720,7 +1731,7 @@ fn test_recvmmsg_timestampns() {
fn test_recvmsg_rxq_ovfl() {
use nix::Error;
use nix::sys::socket::*;
- use nix::sys::uio::IoVec;
+ use std::io::{IoSlice, IoSliceMut};
use nix::sys::socket::sockopt::{RxqOvfl, RcvBuf};
let message = [0u8; 2048];
@@ -1752,7 +1763,7 @@ fn test_recvmsg_rxq_ovfl() {
let mut drop_counter = 0;
for _ in 0..2 {
- let iov = [IoVec::from_slice(&message)];
+ let iov = [IoSlice::new(&message)];
let flags = MsgFlags::empty();
// Send the 3 messages (the receiver buffer can only hold 2 messages)
@@ -1767,11 +1778,11 @@ fn test_recvmsg_rxq_ovfl() {
let mut buffer = vec![0u8; message.len()];
let mut cmsgspace = nix::cmsg_space!(u32);
- let iov = [IoVec::from_mut_slice(&mut buffer)];
+ let mut iov = [IoSliceMut::new(&mut buffer)];
match recvmsg::<()>(
in_socket,
- &iov,
+ &mut iov,
Some(&mut cmsgspace),
MsgFlags::MSG_DONTWAIT) {
Ok(r) => {
@@ -1904,7 +1915,7 @@ mod linux_errqueue {
TESTF: FnOnce(&ControlMessageOwned) -> libc::sock_extended_err,
{
use nix::errno::Errno;
- use nix::sys::uio::IoVec;
+ use std::io::IoSliceMut;
const MESSAGE_CONTENTS: &str = "ABCDEF";
let std_sa = std::net::SocketAddr::from_str(sa).unwrap();
@@ -1918,13 +1929,12 @@ mod linux_errqueue {
}
let mut buf = [0u8; 8];
- let iovec = [IoVec::from_mut_slice(&mut buf)];
+ let mut iovec = [IoSliceMut::new(&mut buf)];
let mut cspace = cmsg_space!(libc::sock_extended_err, SA);
- let msg = recvmsg(sock, &iovec, Some(&mut cspace), MsgFlags::MSG_ERRQUEUE).unwrap();
+ let msg = recvmsg(sock, &mut iovec, Some(&mut cspace), MsgFlags::MSG_ERRQUEUE).unwrap();
// The sent message / destination associated with the error is returned:
assert_eq!(msg.bytes, MESSAGE_CONTENTS.as_bytes().len());
- assert_eq!(&buf[..msg.bytes], MESSAGE_CONTENTS.as_bytes());
// recvmsg(2): "The original destination address of the datagram that caused the error is
// supplied via msg_name;" however, this is not literally true. E.g., an earlier version
// of this test used 0.0.0.0 (::0) as the destination address, which was mutated into
@@ -1945,6 +1955,9 @@ mod linux_errqueue {
assert_eq!(ext_err.ee_code, ee_code);
// ip(7): ee_info contains the discovered MTU for EMSGSIZE errors.
assert_eq!(ext_err.ee_info, 0);
+
+ let bytes = msg.bytes;
+ assert_eq!(&buf[..bytes], MESSAGE_CONTENTS.as_bytes());
}
}
@@ -1989,7 +2002,7 @@ pub fn test_txtime() {
bind(rsock, &sock_addr).unwrap();
let sbuf = [0u8; 2048];
- let iov1 = [nix::sys::uio::IoVec::from_slice(&sbuf)];
+ let iov1 = [std::io::IoSlice::new(&sbuf)];
let now = clock_gettime(ClockId::CLOCK_MONOTONIC).unwrap();
let delay = std::time::Duration::from_secs(1).into();
@@ -1999,6 +2012,6 @@ pub fn test_txtime() {
sendmsg(ssock, &iov1, &[cmsg], MsgFlags::empty(), Some(&sock_addr)).unwrap();
let mut rbuf = [0u8; 2048];
- let iov2 = [nix::sys::uio::IoVec::from_mut_slice(&mut rbuf)];
- recvmsg::<()>(rsock, &iov2, None, MsgFlags::empty()).unwrap();
+ let mut iov2 = [std::io::IoSliceMut::new(&mut rbuf)];
+ recvmsg::<()>(rsock, &mut iov2, None, MsgFlags::empty()).unwrap();
}
diff --git a/test/sys/test_uio.rs b/test/sys/test_uio.rs
index 5353c516..7dd12a21 100644
--- a/test/sys/test_uio.rs
+++ b/test/sys/test_uio.rs
@@ -4,9 +4,13 @@ use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;
use std::{cmp, iter};
use std::fs::{OpenOptions};
+use std::io::IoSlice;
use std::os::unix::io::AsRawFd;
#[cfg(not(target_os = "redox"))]
+use std::io::IoSliceMut;
+
+#[cfg(not(target_os = "redox"))]
use tempfile::tempfile;
use tempfile::tempdir;
@@ -29,7 +33,7 @@ fn test_writev() {
let left = to_write.len() - consumed;
let slice_len = if left <= 64 { left } else { thread_rng().gen_range(64..cmp::min(256, left)) };
let b = &to_write[consumed..consumed+slice_len];
- iovecs.push(IoVec::from_slice(b));
+ iovecs.push(IoSlice::new(b));
consumed += slice_len;
}
let pipe_res = pipe();
@@ -78,7 +82,7 @@ fn test_readv() {
}
let mut iovecs = Vec::with_capacity(storage.len());
for v in &mut storage {
- iovecs.push(IoVec::from_mut_slice(&mut v[..]));
+ iovecs.push(IoSliceMut::new(&mut v[..]));
}
let pipe_res = pipe();
assert!(pipe_res.is_ok());
@@ -95,7 +99,7 @@ fn test_readv() {
// Cccumulate data from iovecs
let mut read_buf = Vec::with_capacity(to_write.len());
for iovec in &iovecs {
- read_buf.extend(iovec.as_slice().iter().cloned());
+ read_buf.extend(iovec.iter().cloned());
}
// Check whether iovecs contain all written data
assert_eq!(read_buf.len(), to_write.len());
@@ -149,9 +153,9 @@ fn test_pwritev() {
let expected: Vec<u8> = [vec![0;100], to_write.clone()].concat();
let iovecs = [
- IoVec::from_slice(&to_write[0..17]),
- IoVec::from_slice(&to_write[17..64]),
- IoVec::from_slice(&to_write[64..128]),
+ IoSlice::new(&to_write[0..17]),
+ IoSlice::new(&to_write[17..64]),
+ IoSlice::new(&to_write[64..128]),
];
let tempdir = tempdir().unwrap();
@@ -194,9 +198,9 @@ fn test_preadv() {
{
// Borrow the buffers into IoVecs and preadv into them
- let iovecs: Vec<_> = buffers.iter_mut().map(
- |buf| IoVec::from_mut_slice(&mut buf[..])).collect();
- assert_eq!(Ok(100), preadv(file.as_raw_fd(), &iovecs, 100));
+ let mut iovecs: Vec<_> = buffers.iter_mut().map(
+ |buf| IoSliceMut::new(&mut buf[..])).collect();
+ assert_eq!(Ok(100), preadv(file.as_raw_fd(), &mut iovecs, 100));
}
let all = buffers.concat();
@@ -233,7 +237,7 @@ fn test_process_vm_readv() {
let mut buf = vec![0u8; 5];
let ret = process_vm_readv(child,
- &[IoVec::from_mut_slice(&mut buf)],
+ &mut [IoSliceMut::new(&mut buf)],
&[remote_iov]);
kill(child, SIGTERM).unwrap();
diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs
index 95e224e2..ebfc43e2 100644
--- a/test/test_fcntl.rs
+++ b/test/test_fcntl.rs
@@ -218,12 +218,11 @@ fn test_readlink() {
#[cfg(any(target_os = "linux", target_os = "android"))]
mod linux_android {
use std::io::prelude::*;
- use std::io::SeekFrom;
+ use std::io::{IoSlice, SeekFrom};
use std::os::unix::prelude::*;
use libc::loff_t;
use nix::fcntl::*;
- use nix::sys::uio::IoVec;
use nix::unistd::{close, pipe, read, write};
use tempfile::tempfile;
@@ -323,8 +322,8 @@ mod linux_android {
let buf1 = b"abcdef";
let buf2 = b"defghi";
let iovecs = vec![
- IoVec::from_slice(&buf1[0..3]),
- IoVec::from_slice(&buf2[0..3])
+ IoSlice::new(&buf1[0..3]),
+ IoSlice::new(&buf2[0..3])
];
let res = vmsplice(wr, &iovecs[..], SpliceFFlags::empty()).unwrap();