use std::ffi::CString;
use std::fs::File;
use std::io;
use std::os::unix::prelude::FromRawFd;
use std::os::unix::prelude::OsStrExt;
use std::path::Path;
use std::sync::Arc;
use crate::SessionACL;
use crate::dev_fuse::DevFuse;
use crate::mnt::MountOption;
use crate::mnt::fuse2_sys::*;
use crate::mnt::with_fuse_args;
fn ensure_last_os_error() -> io::Error {
let err = io::Error::last_os_error();
match err.raw_os_error() {
Some(0) => io::Error::new(io::ErrorKind::Other, "Unspecified Error"),
_ => err,
}
}
#[derive(Debug)]
pub(crate) struct MountImpl {
mountpoint: CString,
}
impl MountImpl {
pub(crate) fn new(
mountpoint: &Path,
options: &[MountOption],
acl: SessionACL,
) -> io::Result<(Arc<DevFuse>, MountImpl)> {
let mountpoint = CString::new(mountpoint.as_os_str().as_bytes()).unwrap();
with_fuse_args(options, acl, |args| {
let fd = unsafe { fuse_mount_compat25(mountpoint.as_ptr(), args) };
if fd < 0 {
Err(ensure_last_os_error())
} else {
let file = unsafe { File::from_raw_fd(fd) };
Ok((Arc::new(DevFuse(file)), MountImpl { mountpoint }))
}
})
}
pub(crate) fn umount_impl(&mut self) -> io::Result<()> {
if let Err(err) = crate::mnt::libc_umount(&self.mountpoint) {
if err == nix::errno::Errno::EPERM {
#[cfg(not(any(
target_os = "macos",
target_os = "freebsd",
target_os = "dragonfly",
target_os = "openbsd",
target_os = "netbsd"
)))]
unsafe {
fuse_unmount_compat22(self.mountpoint.as_ptr());
return Ok(());
}
}
return Err(err.into());
}
Ok(())
}
}