1use crate::*;
2use std::{convert::TryFrom, mem::MaybeUninit, ptr};
3
4#[man(mount(2))]
5pub fn mount<'a, 'b, 'c, 'd>(
6 src: impl IntoUstr<'a>,
7 target: impl IntoUstr<'b>,
8 fstype: impl IntoUstr<'c>,
9 flags: c::c_ulong,
10 data: Option<&'d [MaybeUninit<u8>]>,
11) -> Result<()> {
12 let src = src.into_ustr();
13 let target = target.into_ustr();
14 let fstype = fstype.into_ustr();
15 let data = data
16 .map(|d| black_box_id(d.as_ptr()) as *const _)
17 .unwrap_or(ptr::null());
18 let res = unsafe {
19 c::mount(
20 src.as_ptr(),
21 target.as_ptr(),
22 fstype.as_ptr_null(),
23 flags,
24 data,
25 )
26 };
27 map_err!(res).map(drop)
28}
29
30#[man(umount2(2))]
31pub fn umount2<'a>(target: impl IntoUstr<'a>, flags: c::c_int) -> Result<()> {
32 let target = target.into_ustr();
33 let res = unsafe { c::umount2(target.as_ptr(), flags) };
34 map_err!(res).map(drop)
35}
36
37pub fn open_tree<'a>(
39 dfd: c::c_int,
40 filename: impl IntoUstr<'a>,
41 flags: c::c_uint,
42) -> Result<OwnedFd> {
43 let filename = filename.into_ustr();
44 let res = unsafe { c::open_tree(dfd, filename.as_ptr(), flags) };
45 map_err!(res).map(OwnedFd::new)
46}
47
48pub fn move_mount<'a, 'b>(
50 from_dfd: c::c_int,
51 from_pathname: impl IntoUstr<'a>,
52 to_dfd: c::c_int,
53 to_pathname: impl IntoUstr<'b>,
54 flags: c::c_uint,
55) -> Result<()> {
56 let from_pathname = from_pathname.into_ustr();
57 let to_pathname = to_pathname.into_ustr();
58 let res = unsafe {
59 c::move_mount(
60 from_dfd,
61 from_pathname.as_ptr(),
62 to_dfd,
63 to_pathname.as_ptr(),
64 flags,
65 )
66 };
67 map_err!(res).map(drop)
68}
69
70pub fn fsopen<'a>(fs_name: impl IntoUstr<'a>, flags: c::c_uint) -> Result<OwnedFd> {
72 let fs_name = fs_name.into_ustr();
73 let res = unsafe { c::fsopen(fs_name.as_ptr(), flags) };
74 map_err!(res).map(OwnedFd::new)
75}
76
77pub fn fsconfig_set_flag<'a>(fs_fd: c::c_int, key: impl IntoUstr<'a>) -> Result<()> {
79 let key = key.into_ustr();
80 let res =
81 unsafe { c::fsconfig(fs_fd, c::FSCONFIG_SET_FLAG, key.as_ptr(), ptr::null(), 0) };
82 map_err!(res).map(drop)
83}
84
85pub fn fsconfig_set_string<'a, 'b>(
87 fs_fd: c::c_int,
88 key: impl IntoUstr<'a>,
89 value: impl IntoUstr<'b>,
90) -> Result<()> {
91 let key = key.into_ustr();
92 let value = value.into_ustr();
93 let res = unsafe {
94 c::fsconfig(
95 fs_fd,
96 c::FSCONFIG_SET_STRING,
97 key.as_ptr(),
98 value.as_ptr() as *const c::c_void,
99 0,
100 )
101 };
102 map_err!(res).map(drop)
103}
104
105pub fn fsconfig_set_binary<'a, T: ?Sized>(
107 fs_fd: c::c_int,
108 key: impl IntoUstr<'a>,
109 value: &T,
110) -> Result<()> {
111 let key = key.into_ustr();
112 let value = as_maybe_uninit_bytes(value);
113 let len = match c::c_int::try_from(value.len()) {
114 Ok(len) => len,
115 Err(_) => return Err(Errno(c::EINVAL)),
116 };
117 let res = unsafe {
118 c::fsconfig(
119 fs_fd,
120 c::FSCONFIG_SET_BINARY,
121 key.as_ptr(),
122 black_box_id(value.as_ptr()) as *const c::c_void,
123 len,
124 )
125 };
126 map_err!(res).map(drop)
127}
128
129fn _fsconfig_set_path<'a, 'b>(
130 fs_fd: c::c_int,
131 cmd: c::c_uint,
132 key: impl IntoUstr<'a>,
133 dfd: c::c_int,
134 path: impl IntoUstr<'b>,
135) -> Result<()> {
136 let key = key.into_ustr();
137 let path = path.into_ustr();
138 let res = unsafe {
139 c::fsconfig(
140 fs_fd,
141 cmd,
142 key.as_ptr(),
143 path.as_ptr() as *const c::c_void,
144 dfd,
145 )
146 };
147 map_err!(res).map(drop)
148}
149
150pub fn fsconfig_set_path<'a, 'b>(
152 fs_fd: c::c_int,
153 key: impl IntoUstr<'a>,
154 dfd: c::c_int,
155 path: impl IntoUstr<'b>,
156) -> Result<()> {
157 _fsconfig_set_path(fs_fd, c::FSCONFIG_SET_PATH, key, dfd, path)
158}
159
160pub fn fsconfig_set_path_empty<'a, 'b>(
162 fs_fd: c::c_int,
163 key: impl IntoUstr<'a>,
164 dfd: c::c_int,
165 path: impl IntoUstr<'b>,
166) -> Result<()> {
167 _fsconfig_set_path(fs_fd, c::FSCONFIG_SET_PATH_EMPTY, key, dfd, path)
168}
169
170pub fn fsconfig_set_fd<'a>(
172 fs_fd: c::c_int,
173 key: impl IntoUstr<'a>,
174 fd: c::c_int,
175) -> Result<()> {
176 let key = key.into_ustr();
177 let res =
178 unsafe { c::fsconfig(fs_fd, c::FSCONFIG_SET_FD, key.as_ptr(), ptr::null(), fd) };
179 map_err!(res).map(drop)
180}
181
182fn _fsconfig_cmd(fs_fd: c::c_int, cmd: c::c_uint) -> Result<()> {
183 let res = unsafe { c::fsconfig(fs_fd, cmd, ptr::null(), ptr::null(), 0) };
184 map_err!(res).map(drop)
185}
186
187pub fn fsconfig_cmd_create(fs_fd: c::c_int) -> Result<()> {
189 _fsconfig_cmd(fs_fd, c::FSCONFIG_CMD_CREATE)
190}
191
192pub fn fsconfig_cmd_reconfigure(fs_fd: c::c_int) -> Result<()> {
194 _fsconfig_cmd(fs_fd, c::FSCONFIG_CMD_RECONFIGURE)
195}
196
197pub fn fsmount(
199 fs_fd: c::c_int,
200 flags: c::c_uint,
201 attr_flags: c::c_uint,
202) -> Result<OwnedFd> {
203 let res = unsafe { c::fsmount(fs_fd, flags, attr_flags) };
204 map_err!(res).map(OwnedFd::new)
205}
206
207pub fn fspick<'a>(
209 dfd: c::c_int,
210 path: impl IntoUstr<'a>,
211 flags: c::c_uint,
212) -> Result<OwnedFd> {
213 let path = path.into_ustr();
214 let res = unsafe { c::fspick(dfd, path.as_ptr(), flags) };
215 map_err!(res).map(OwnedFd::new)
216}