summaryrefslogtreecommitdiff
path: root/src/mount/bsd.rs
diff options
context:
space:
mode:
authornot_a_seagull <notaseagull048@gmail.com>2022-01-23 11:43:25 -0800
committernot_a_seagull <notaseagull048@gmail.com>2022-04-08 12:39:16 -0700
commit0b58f2977252739629b5175043d705f7fc76ea8d (patch)
treeae028d4613a1c6752fe729e870d4b9ff3c7388b1 /src/mount/bsd.rs
parentc59a8c8cc6cc6922888d6f33635905f9ea3d3205 (diff)
downloadnix-0b58f2977252739629b5175043d705f7fc76ea8d.zip
Replace the IoVec type with IoSlice and IoSliceMut
Diffstat (limited to 'src/mount/bsd.rs')
-rw-r--r--src/mount/bsd.rs111
1 files changed, 56 insertions, 55 deletions
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));
}
}
}