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} 116