1//! Linux `mount`.
2
3use crate::backend::mount::types::{
4 InternalMountFlags, MountFlags, MountFlagsArg, MountPropagationFlags, UnmountFlags,
5};
6use crate::ffi::CStr;
7use crate::path::{self, option_into_with_c_str};
8use crate::{backend, io};
9
10/// `mount(source, target, filesystemtype, mountflags, data)`
11///
12/// # References
13/// - [Linux]
14///
15/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html
16#[inline]
17pub fn mount<Source: path::Arg, Target: path::Arg, Fs: path::Arg, Data: path::Arg>(
18 source: Source,
19 target: Target,
20 file_system_type: Fs,
21 flags: MountFlags,
22 data: Data,
23) -> io::Result<()> {
24 source.into_with_c_str(|source: &CStr| {
25 target.into_with_c_str(|target: &CStr| {
26 file_system_type.into_with_c_str(|file_system_type: &CStr| {
27 data.into_with_c_str(|data: &CStr| {
28 backend::mount::syscalls::mount(
29 source:Some(source),
30 target,
31 file_system_type:Some(file_system_type),
32 flags:MountFlagsArg(flags.bits()),
33 data:Some(data),
34 )
35 })
36 })
37 })
38 })
39}
40
41/// `mount2(source, target, filesystemtype, mountflags, data)`
42///
43/// This is same as the [`mount`], except it adds support for
44/// the source, target, and data being omitted, and the data
45/// is passed as a `CStr` rather than a `path::Arg`.
46///
47/// # References
48/// - [Linux]
49///
50/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html
51#[inline]
52pub fn mount2<Source: path::Arg, Target: path::Arg, Fs: path::Arg>(
53 source: Option<Source>,
54 target: Target,
55 file_system_type: Option<Fs>,
56 flags: MountFlags,
57 data: Option<&CStr>,
58) -> io::Result<()> {
59 option_into_with_c_str(arg:source, |source: Option<&CStr>| {
60 target.into_with_c_str(|target: &CStr| {
61 option_into_with_c_str(arg:file_system_type, |file_system_type: Option<&CStr>| {
62 backend::mount::syscalls::mount(
63 source,
64 target,
65 file_system_type,
66 flags:MountFlagsArg(flags.bits()),
67 data,
68 )
69 })
70 })
71 })
72}
73
74/// `mount(NULL, target, NULL, MS_REMOUNT | mountflags, data)`
75///
76/// # References
77/// - [Linux]
78///
79/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html
80#[inline]
81#[doc(alias = "mount")]
82#[doc(alias = "MS_REMOUNT")]
83pub fn mount_remount<Target: path::Arg, Data: path::Arg>(
84 target: Target,
85 flags: MountFlags,
86 data: Data,
87) -> io::Result<()> {
88 target.into_with_c_str(|target: &CStr| {
89 data.into_with_c_str(|data: &CStr| {
90 backend::mount::syscalls::mount(
91 source:None,
92 target,
93 file_system_type:None,
94 flags:MountFlagsArg(InternalMountFlags::REMOUNT.bits() | flags.bits()),
95 data:Some(data),
96 )
97 })
98 })
99}
100
101/// `mount(source, target, NULL, MS_BIND, NULL)`
102///
103/// # References
104/// - [Linux]
105///
106/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html
107#[inline]
108#[doc(alias = "mount")]
109#[doc(alias = "MS_BIND")]
110pub fn mount_bind<Source: path::Arg, Target: path::Arg>(
111 source: Source,
112 target: Target,
113) -> io::Result<()> {
114 source.into_with_c_str(|source: &CStr| {
115 target.into_with_c_str(|target: &CStr| {
116 backend::mount::syscalls::mount(
117 source:Some(source),
118 target,
119 file_system_type:None,
120 flags:MountFlagsArg(MountFlags::BIND.bits()),
121 data:None,
122 )
123 })
124 })
125}
126
127/// `mount(source, target, NULL, MS_BIND | MS_REC, NULL)`
128///
129/// # References
130/// - [Linux]
131///
132/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html
133#[inline]
134#[doc(alias = "mount")]
135#[doc(alias = "MS_REC")]
136pub fn mount_recursive_bind<Source: path::Arg, Target: path::Arg>(
137 source: Source,
138 target: Target,
139) -> io::Result<()> {
140 source.into_with_c_str(|source: &CStr| {
141 target.into_with_c_str(|target: &CStr| {
142 backend::mount::syscalls::mount(
143 source:Some(source),
144 target,
145 file_system_type:None,
146 flags:MountFlagsArg(MountFlags::BIND.bits() | MountPropagationFlags::REC.bits()),
147 data:None,
148 )
149 })
150 })
151}
152
153/// `mount(NULL, target, NULL, mountflags, NULL)`
154///
155/// # References
156/// - [Linux]
157///
158/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html
159#[inline]
160#[doc(alias = "mount")]
161pub fn mount_change<Target: path::Arg>(
162 target: Target,
163 flags: MountPropagationFlags,
164) -> io::Result<()> {
165 target.into_with_c_str(|target: &CStr| {
166 backend::mount::syscalls::mount(source:None, target, file_system_type:None, flags:MountFlagsArg(flags.bits()), data:None)
167 })
168}
169
170/// `mount(source, target, NULL, MS_MOVE, NULL)`
171///
172/// This is not the same as the `move_mount` syscall. If you want to use that,
173/// use [`move_mount`] instead.
174///
175/// # References
176/// - [Linux]
177///
178/// [`move_mount`]: crate::mount::move_mount
179/// [Linux]: https://man7.org/linux/man-pages/man2/mount.2.html
180#[inline]
181#[doc(alias = "mount")]
182#[doc(alias = "MS_MOVE")]
183pub fn mount_move<Source: path::Arg, Target: path::Arg>(
184 source: Source,
185 target: Target,
186) -> io::Result<()> {
187 source.into_with_c_str(|source: &CStr| {
188 target.into_with_c_str(|target: &CStr| {
189 backend::mount::syscalls::mount(
190 source:Some(source),
191 target,
192 file_system_type:None,
193 flags:MountFlagsArg(InternalMountFlags::MOVE.bits()),
194 data:None,
195 )
196 })
197 })
198}
199
200/// `umount2(target, flags)`
201///
202/// # References
203/// - [Linux]
204///
205/// [Linux]: https://man7.org/linux/man-pages/man2/umount.2.html
206#[inline]
207#[doc(alias = "umount", alias = "umount2")]
208pub fn unmount<Target: path::Arg>(target: Target, flags: UnmountFlags) -> io::Result<()> {
209 target.into_with_c_str(|target: &CStr| backend::mount::syscalls::unmount(target, flags))
210}
211