use crate::*;
use std::{convert::TryFrom, mem::MaybeUninit, ptr};
#[man(mount(2))]
pub fn mount<'a, 'b, 'c, 'd>(
src: impl IntoUstr<'a>,
target: impl IntoUstr<'b>,
fstype: impl IntoUstr<'c>,
flags: c::c_ulong,
data: Option<&'d [MaybeUninit<u8>]>,
) -> Result<()> {
let src = src.into_ustr();
let target = target.into_ustr();
let fstype = fstype.into_ustr();
let data = data
.map(|d| black_box_id(d.as_ptr()) as *const _)
.unwrap_or(ptr::null());
let res = unsafe {
c::mount(
src.as_ptr(),
target.as_ptr(),
fstype.as_ptr_null(),
flags,
data,
)
};
map_err!(res).map(drop)
}
#[man(umount2(2))]
pub fn umount2<'a>(target: impl IntoUstr<'a>, flags: c::c_int) -> Result<()> {
let target = target.into_ustr();
let res = unsafe { c::umount2(target.as_ptr(), flags) };
map_err!(res).map(drop)
}
pub fn open_tree<'a>(
dfd: c::c_int,
filename: impl IntoUstr<'a>,
flags: c::c_uint,
) -> Result<OwnedFd> {
let filename = filename.into_ustr();
let res = unsafe { c::open_tree(dfd, filename.as_ptr(), flags) };
map_err!(res).map(OwnedFd::new)
}
pub fn move_mount<'a, 'b>(
from_dfd: c::c_int,
from_pathname: impl IntoUstr<'a>,
to_dfd: c::c_int,
to_pathname: impl IntoUstr<'b>,
flags: c::c_uint,
) -> Result<()> {
let from_pathname = from_pathname.into_ustr();
let to_pathname = to_pathname.into_ustr();
let res = unsafe {
c::move_mount(
from_dfd,
from_pathname.as_ptr(),
to_dfd,
to_pathname.as_ptr(),
flags,
)
};
map_err!(res).map(drop)
}
pub fn fsopen<'a>(fs_name: impl IntoUstr<'a>, flags: c::c_uint) -> Result<OwnedFd> {
let fs_name = fs_name.into_ustr();
let res = unsafe { c::fsopen(fs_name.as_ptr(), flags) };
map_err!(res).map(OwnedFd::new)
}
pub fn fsconfig_set_flag<'a>(fs_fd: c::c_int, key: impl IntoUstr<'a>) -> Result<()> {
let key = key.into_ustr();
let res =
unsafe { c::fsconfig(fs_fd, c::FSCONFIG_SET_FLAG, key.as_ptr(), ptr::null(), 0) };
map_err!(res).map(drop)
}
pub fn fsconfig_set_string<'a, 'b>(
fs_fd: c::c_int,
key: impl IntoUstr<'a>,
value: impl IntoUstr<'b>,
) -> Result<()> {
let key = key.into_ustr();
let value = value.into_ustr();
let res = unsafe {
c::fsconfig(
fs_fd,
c::FSCONFIG_SET_STRING,
key.as_ptr(),
value.as_ptr() as *const c::c_void,
0,
)
};
map_err!(res).map(drop)
}
pub fn fsconfig_set_binary<'a, T: ?Sized>(
fs_fd: c::c_int,
key: impl IntoUstr<'a>,
value: &T,
) -> Result<()> {
let key = key.into_ustr();
let value = as_maybe_uninit_bytes(value);
let len = match c::c_int::try_from(value.len()) {
Ok(len) => len,
Err(_) => return Err(Errno(c::EINVAL)),
};
let res = unsafe {
c::fsconfig(
fs_fd,
c::FSCONFIG_SET_BINARY,
key.as_ptr(),
black_box_id(value.as_ptr()) as *const c::c_void,
len,
)
};
map_err!(res).map(drop)
}
fn _fsconfig_set_path<'a, 'b>(
fs_fd: c::c_int,
cmd: c::c_uint,
key: impl IntoUstr<'a>,
dfd: c::c_int,
path: impl IntoUstr<'b>,
) -> Result<()> {
let key = key.into_ustr();
let path = path.into_ustr();
let res = unsafe {
c::fsconfig(
fs_fd,
cmd,
key.as_ptr(),
path.as_ptr() as *const c::c_void,
dfd,
)
};
map_err!(res).map(drop)
}
pub fn fsconfig_set_path<'a, 'b>(
fs_fd: c::c_int,
key: impl IntoUstr<'a>,
dfd: c::c_int,
path: impl IntoUstr<'b>,
) -> Result<()> {
_fsconfig_set_path(fs_fd, c::FSCONFIG_SET_PATH, key, dfd, path)
}
pub fn fsconfig_set_path_empty<'a, 'b>(
fs_fd: c::c_int,
key: impl IntoUstr<'a>,
dfd: c::c_int,
path: impl IntoUstr<'b>,
) -> Result<()> {
_fsconfig_set_path(fs_fd, c::FSCONFIG_SET_PATH_EMPTY, key, dfd, path)
}
pub fn fsconfig_set_fd<'a>(
fs_fd: c::c_int,
key: impl IntoUstr<'a>,
fd: c::c_int,
) -> Result<()> {
let key = key.into_ustr();
let res =
unsafe { c::fsconfig(fs_fd, c::FSCONFIG_SET_FD, key.as_ptr(), ptr::null(), fd) };
map_err!(res).map(drop)
}
fn _fsconfig_cmd(fs_fd: c::c_int, cmd: c::c_uint) -> Result<()> {
let res = unsafe { c::fsconfig(fs_fd, cmd, ptr::null(), ptr::null(), 0) };
map_err!(res).map(drop)
}
pub fn fsconfig_cmd_create(fs_fd: c::c_int) -> Result<()> {
_fsconfig_cmd(fs_fd, c::FSCONFIG_CMD_CREATE)
}
pub fn fsconfig_cmd_reconfigure(fs_fd: c::c_int) -> Result<()> {
_fsconfig_cmd(fs_fd, c::FSCONFIG_CMD_RECONFIGURE)
}
pub fn fsmount(
fs_fd: c::c_int,
flags: c::c_uint,
attr_flags: c::c_uint,
) -> Result<OwnedFd> {
let res = unsafe { c::fsmount(fs_fd, flags, attr_flags) };
map_err!(res).map(OwnedFd::new)
}
pub fn fspick<'a>(
dfd: c::c_int,
path: impl IntoUstr<'a>,
flags: c::c_uint,
) -> Result<OwnedFd> {
let path = path.into_ustr();
let res = unsafe { c::fspick(dfd, path.as_ptr(), flags) };
map_err!(res).map(OwnedFd::new)
}