nix/mount/
linux.rs

1#![allow(missing_docs)]
2use crate::errno::Errno;
3use crate::{NixPath, Result};
4use libc::{self, c_int, c_ulong};
5
6libc_bitflags!(
7    pub struct MsFlags: c_ulong {
8        /// Mount read-only
9        MS_RDONLY;
10        /// Ignore suid and sgid bits
11        MS_NOSUID;
12        /// Disallow access to device special files
13        MS_NODEV;
14        /// Disallow program execution
15        MS_NOEXEC;
16        /// Writes are synced at once
17        MS_SYNCHRONOUS;
18        /// Alter flags of a mounted FS
19        MS_REMOUNT;
20        /// Allow mandatory locks on a FS
21        MS_MANDLOCK;
22        /// Directory modifications are synchronous
23        MS_DIRSYNC;
24        /// Do not update access times
25        MS_NOATIME;
26        /// Do not update directory access times
27        MS_NODIRATIME;
28        /// Linux 2.4.0 - Bind directory at different place
29        MS_BIND;
30        MS_MOVE;
31        MS_REC;
32        MS_SILENT;
33        MS_POSIXACL;
34        MS_UNBINDABLE;
35        MS_PRIVATE;
36        MS_SLAVE;
37        MS_SHARED;
38        MS_RELATIME;
39        MS_KERNMOUNT;
40        MS_I_VERSION;
41        MS_STRICTATIME;
42        MS_LAZYTIME;
43        MS_ACTIVE;
44        MS_NOUSER;
45        MS_RMT_MASK;
46        MS_MGC_VAL;
47        MS_MGC_MSK;
48    }
49);
50
51libc_bitflags!(
52    pub struct MntFlags: c_int {
53        MNT_FORCE;
54        MNT_DETACH;
55        MNT_EXPIRE;
56        UMOUNT_NOFOLLOW;
57    }
58);
59
60pub fn mount<
61    P1: ?Sized + NixPath,
62    P2: ?Sized + NixPath,
63    P3: ?Sized + NixPath,
64    P4: ?Sized + NixPath,
65>(
66    source: Option<&P1>,
67    target: &P2,
68    fstype: Option<&P3>,
69    flags: MsFlags,
70    data: Option<&P4>,
71) -> Result<()> {
72    fn with_opt_nix_path<P, T, F>(p: Option<&P>, f: F) -> Result<T>
73    where
74        P: ?Sized + NixPath,
75        F: FnOnce(*const libc::c_char) -> T,
76    {
77        match p {
78            Some(path) => path.with_nix_path(|p_str| f(p_str.as_ptr())),
79            None => Ok(f(std::ptr::null())),
80        }
81    }
82
83    let res = with_opt_nix_path(source, |s| {
84        target.with_nix_path(|t| {
85            with_opt_nix_path(fstype, |ty| {
86                with_opt_nix_path(data, |d| unsafe {
87                    libc::mount(
88                        s,
89                        t.as_ptr(),
90                        ty,
91                        flags.bits,
92                        d as *const libc::c_void,
93                    )
94                })
95            })
96        })
97    })????;
98
99    Errno::result(res).map(drop)
100}
101
102pub fn umount<P: ?Sized + NixPath>(target: &P) -> Result<()> {
103    let res =
104        target.with_nix_path(|cstr| unsafe { libc::umount(cstr.as_ptr()) })?;
105
106    Errno::result(res).map(drop)
107}
108
109pub fn umount2<P: ?Sized + NixPath>(target: &P, flags: MntFlags) -> Result<()> {
110    let res = target.with_nix_path(|cstr| unsafe {
111        libc::umount2(cstr.as_ptr(), flags.bits)
112    })?;
113
114    Errno::result(res).map(drop)
115}