|
@@ -8,12 +8,19 @@ use crate::fs::mounts::{Error, MountedFs};
|
|
|
|
|
|
|
|
/// Get a list of all mounted filesystem
|
|
/// Get a list of all mounted filesystem
|
|
|
pub fn mounts() -> Result<Vec<MountedFs>, Error> {
|
|
pub fn mounts() -> Result<Vec<MountedFs>, Error> {
|
|
|
- // Passing a null pointer and zero bufsize will return the number of mounts
|
|
|
|
|
|
|
+ // SAFETY:
|
|
|
|
|
+ // Calling external "C" function getfsstat. Passing a null pointer and zero
|
|
|
|
|
+ // bufsize will return the number of mounts.
|
|
|
let mut count: i32 = unsafe { getfsstat(ptr::null_mut(), 0, MNT_NOWAIT) };
|
|
let mut count: i32 = unsafe { getfsstat(ptr::null_mut(), 0, MNT_NOWAIT) };
|
|
|
let mut mntbuf = Vec::<statfs>::new();
|
|
let mut mntbuf = Vec::<statfs>::new();
|
|
|
if count > 0 {
|
|
if count > 0 {
|
|
|
|
|
+ // SAFETY: Zero out buffer memory as we allocate.
|
|
|
mntbuf.resize_with(count as usize, || unsafe { mem::zeroed() });
|
|
mntbuf.resize_with(count as usize, || unsafe { mem::zeroed() });
|
|
|
let bufsize = mntbuf.len() * mem::size_of::<statfs>();
|
|
let bufsize = mntbuf.len() * mem::size_of::<statfs>();
|
|
|
|
|
+ // SAFETY:
|
|
|
|
|
+ // Calling external "C" function getfsstate with actual buffer now. The
|
|
|
|
|
+ // function takes a buffer size to not overflow. If the mount table
|
|
|
|
|
+ // changes size between calls we are protected by bufsize
|
|
|
count = unsafe { getfsstat(mntbuf.as_mut_ptr(), bufsize as c_int, MNT_NOWAIT) };
|
|
count = unsafe { getfsstat(mntbuf.as_mut_ptr(), bufsize as c_int, MNT_NOWAIT) };
|
|
|
// Resize if the mount table has shrunk since last call
|
|
// Resize if the mount table has shrunk since last call
|
|
|
if count >= 0 {
|
|
if count >= 0 {
|
|
@@ -21,18 +28,22 @@ pub fn mounts() -> Result<Vec<MountedFs>, Error> {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
if count < 0 {
|
|
if count < 0 {
|
|
|
|
|
+ // SAFETY: Calling external "C" errno function to get the error number
|
|
|
return Err(Error::GetFSStatError(unsafe { *__error() }));
|
|
return Err(Error::GetFSStatError(unsafe { *__error() }));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
let mut mounts = Vec::with_capacity(count as usize);
|
|
let mut mounts = Vec::with_capacity(count as usize);
|
|
|
for mnt in &mntbuf {
|
|
for mnt in &mntbuf {
|
|
|
let mount_point = OsStr::from_bytes(
|
|
let mount_point = OsStr::from_bytes(
|
|
|
|
|
+ // SAFETY: Converting null terminated "C" string
|
|
|
unsafe { CStr::from_ptr(mnt.f_mntonname.as_ptr().cast::<c_char>()) }.to_bytes()
|
|
unsafe { CStr::from_ptr(mnt.f_mntonname.as_ptr().cast::<c_char>()) }.to_bytes()
|
|
|
);
|
|
);
|
|
|
let dest = PathBuf::from(mount_point);
|
|
let dest = PathBuf::from(mount_point);
|
|
|
|
|
+ // SAFETY: Converting null terminated "C" string
|
|
|
let fstype = unsafe { CStr::from_ptr(mnt.f_fstypename.as_ptr().cast::<c_char>()) }
|
|
let fstype = unsafe { CStr::from_ptr(mnt.f_fstypename.as_ptr().cast::<c_char>()) }
|
|
|
.to_string_lossy()
|
|
.to_string_lossy()
|
|
|
.into();
|
|
.into();
|
|
|
|
|
+ // SAFETY: Converting null terminated "C" string
|
|
|
let source = unsafe { CStr::from_ptr(mnt.f_mntfromname.as_ptr().cast::<c_char>()) }
|
|
let source = unsafe { CStr::from_ptr(mnt.f_mntfromname.as_ptr().cast::<c_char>()) }
|
|
|
.to_string_lossy()
|
|
.to_string_lossy()
|
|
|
.into();
|
|
.into();
|