13da5c369Sopenharmony_ci#![allow(missing_docs)]
23da5c369Sopenharmony_ciuse crate::errno::Errno;
33da5c369Sopenharmony_ciuse crate::{NixPath, Result};
43da5c369Sopenharmony_ciuse libc::{self, c_int, c_ulong};
53da5c369Sopenharmony_ci
63da5c369Sopenharmony_cilibc_bitflags!(
73da5c369Sopenharmony_ci    pub struct MsFlags: c_ulong {
83da5c369Sopenharmony_ci        /// Mount read-only
93da5c369Sopenharmony_ci        MS_RDONLY;
103da5c369Sopenharmony_ci        /// Ignore suid and sgid bits
113da5c369Sopenharmony_ci        MS_NOSUID;
123da5c369Sopenharmony_ci        /// Disallow access to device special files
133da5c369Sopenharmony_ci        MS_NODEV;
143da5c369Sopenharmony_ci        /// Disallow program execution
153da5c369Sopenharmony_ci        MS_NOEXEC;
163da5c369Sopenharmony_ci        /// Writes are synced at once
173da5c369Sopenharmony_ci        MS_SYNCHRONOUS;
183da5c369Sopenharmony_ci        /// Alter flags of a mounted FS
193da5c369Sopenharmony_ci        MS_REMOUNT;
203da5c369Sopenharmony_ci        /// Allow mandatory locks on a FS
213da5c369Sopenharmony_ci        MS_MANDLOCK;
223da5c369Sopenharmony_ci        /// Directory modifications are synchronous
233da5c369Sopenharmony_ci        MS_DIRSYNC;
243da5c369Sopenharmony_ci        /// Do not update access times
253da5c369Sopenharmony_ci        MS_NOATIME;
263da5c369Sopenharmony_ci        /// Do not update directory access times
273da5c369Sopenharmony_ci        MS_NODIRATIME;
283da5c369Sopenharmony_ci        /// Linux 2.4.0 - Bind directory at different place
293da5c369Sopenharmony_ci        MS_BIND;
303da5c369Sopenharmony_ci        MS_MOVE;
313da5c369Sopenharmony_ci        MS_REC;
323da5c369Sopenharmony_ci        MS_SILENT;
333da5c369Sopenharmony_ci        MS_POSIXACL;
343da5c369Sopenharmony_ci        MS_UNBINDABLE;
353da5c369Sopenharmony_ci        MS_PRIVATE;
363da5c369Sopenharmony_ci        MS_SLAVE;
373da5c369Sopenharmony_ci        MS_SHARED;
383da5c369Sopenharmony_ci        MS_RELATIME;
393da5c369Sopenharmony_ci        MS_KERNMOUNT;
403da5c369Sopenharmony_ci        MS_I_VERSION;
413da5c369Sopenharmony_ci        MS_STRICTATIME;
423da5c369Sopenharmony_ci        MS_LAZYTIME;
433da5c369Sopenharmony_ci        MS_ACTIVE;
443da5c369Sopenharmony_ci        MS_NOUSER;
453da5c369Sopenharmony_ci        MS_RMT_MASK;
463da5c369Sopenharmony_ci        MS_MGC_VAL;
473da5c369Sopenharmony_ci        MS_MGC_MSK;
483da5c369Sopenharmony_ci    }
493da5c369Sopenharmony_ci);
503da5c369Sopenharmony_ci
513da5c369Sopenharmony_cilibc_bitflags!(
523da5c369Sopenharmony_ci    pub struct MntFlags: c_int {
533da5c369Sopenharmony_ci        MNT_FORCE;
543da5c369Sopenharmony_ci        MNT_DETACH;
553da5c369Sopenharmony_ci        MNT_EXPIRE;
563da5c369Sopenharmony_ci        UMOUNT_NOFOLLOW;
573da5c369Sopenharmony_ci    }
583da5c369Sopenharmony_ci);
593da5c369Sopenharmony_ci
603da5c369Sopenharmony_cipub fn mount<
613da5c369Sopenharmony_ci    P1: ?Sized + NixPath,
623da5c369Sopenharmony_ci    P2: ?Sized + NixPath,
633da5c369Sopenharmony_ci    P3: ?Sized + NixPath,
643da5c369Sopenharmony_ci    P4: ?Sized + NixPath,
653da5c369Sopenharmony_ci>(
663da5c369Sopenharmony_ci    source: Option<&P1>,
673da5c369Sopenharmony_ci    target: &P2,
683da5c369Sopenharmony_ci    fstype: Option<&P3>,
693da5c369Sopenharmony_ci    flags: MsFlags,
703da5c369Sopenharmony_ci    data: Option<&P4>,
713da5c369Sopenharmony_ci) -> Result<()> {
723da5c369Sopenharmony_ci    fn with_opt_nix_path<P, T, F>(p: Option<&P>, f: F) -> Result<T>
733da5c369Sopenharmony_ci    where
743da5c369Sopenharmony_ci        P: ?Sized + NixPath,
753da5c369Sopenharmony_ci        F: FnOnce(*const libc::c_char) -> T,
763da5c369Sopenharmony_ci    {
773da5c369Sopenharmony_ci        match p {
783da5c369Sopenharmony_ci            Some(path) => path.with_nix_path(|p_str| f(p_str.as_ptr())),
793da5c369Sopenharmony_ci            None => Ok(f(std::ptr::null())),
803da5c369Sopenharmony_ci        }
813da5c369Sopenharmony_ci    }
823da5c369Sopenharmony_ci
833da5c369Sopenharmony_ci    let res = with_opt_nix_path(source, |s| {
843da5c369Sopenharmony_ci        target.with_nix_path(|t| {
853da5c369Sopenharmony_ci            with_opt_nix_path(fstype, |ty| {
863da5c369Sopenharmony_ci                with_opt_nix_path(data, |d| unsafe {
873da5c369Sopenharmony_ci                    libc::mount(
883da5c369Sopenharmony_ci                        s,
893da5c369Sopenharmony_ci                        t.as_ptr(),
903da5c369Sopenharmony_ci                        ty,
913da5c369Sopenharmony_ci                        flags.bits,
923da5c369Sopenharmony_ci                        d as *const libc::c_void,
933da5c369Sopenharmony_ci                    )
943da5c369Sopenharmony_ci                })
953da5c369Sopenharmony_ci            })
963da5c369Sopenharmony_ci        })
973da5c369Sopenharmony_ci    })????;
983da5c369Sopenharmony_ci
993da5c369Sopenharmony_ci    Errno::result(res).map(drop)
1003da5c369Sopenharmony_ci}
1013da5c369Sopenharmony_ci
1023da5c369Sopenharmony_cipub fn umount<P: ?Sized + NixPath>(target: &P) -> Result<()> {
1033da5c369Sopenharmony_ci    let res =
1043da5c369Sopenharmony_ci        target.with_nix_path(|cstr| unsafe { libc::umount(cstr.as_ptr()) })?;
1053da5c369Sopenharmony_ci
1063da5c369Sopenharmony_ci    Errno::result(res).map(drop)
1073da5c369Sopenharmony_ci}
1083da5c369Sopenharmony_ci
1093da5c369Sopenharmony_cipub fn umount2<P: ?Sized + NixPath>(target: &P, flags: MntFlags) -> Result<()> {
1103da5c369Sopenharmony_ci    let res = target.with_nix_path(|cstr| unsafe {
1113da5c369Sopenharmony_ci        libc::umount2(cstr.as_ptr(), flags.bits)
1123da5c369Sopenharmony_ci    })?;
1133da5c369Sopenharmony_ci
1143da5c369Sopenharmony_ci    Errno::result(res).map(drop)
1153da5c369Sopenharmony_ci}
116