#[inline]
pub fn daemon(nochdir: bool, noclose: bool) -> anyhow::Result<()> {
#[allow(unsafe_code)]
match unsafe { libc::daemon(i32::from(nochdir), i32::from(noclose)) } {
0i32 => Ok(()),
_ => Err(anyhow::anyhow!(
"daemon: '{}'",
std::io::Error::last_os_error()
)),
}
}
#[inline]
pub fn setuid(uid: libc::uid_t) -> anyhow::Result<i32> {
#[allow(unsafe_code)]
match unsafe { libc::setuid(uid) } {
-1i32 => Err(anyhow::anyhow!(
"setuid: '{}'",
std::io::Error::last_os_error()
)),
otherwise => Ok(otherwise),
}
}
#[inline]
pub fn setgid(gid: libc::gid_t) -> anyhow::Result<i32> {
#[allow(unsafe_code)]
match unsafe { libc::setgid(gid) } {
-1i32 => Err(anyhow::anyhow!(
"setgid: '{}'",
std::io::Error::last_os_error()
)),
otherwise => Ok(otherwise),
}
}
#[inline]
pub fn initgroups(user: &str, gid: libc::gid_t) -> anyhow::Result<()> {
let user = alloc::ffi::CString::new(user)?;
#[allow(unsafe_code)]
match unsafe { libc::initgroups(user.as_ptr(), gid) } {
0i32 => Ok(()),
_ => Err(anyhow::anyhow!(
"initgroups: '{}'",
std::io::Error::last_os_error()
)),
}
}
#[inline]
pub fn chown(path: &std::path::Path, user: Option<u32>, group: Option<u32>) -> anyhow::Result<()> {
let path = alloc::ffi::CString::new(path.to_string_lossy().as_bytes())?;
#[allow(unsafe_code)]
match unsafe {
libc::chown(
path.as_ptr(),
user.unwrap_or(u32::MAX),
group.unwrap_or(u32::MAX),
)
} {
0i32 => Ok(()),
otherwise => Err(anyhow::anyhow!(
"failed to change file owner: ({}) '{}'",
otherwise,
std::io::Error::last_os_error()
)),
}
}
#[inline]
pub fn if_nametoindex(name: &str) -> anyhow::Result<u32> {
let ifname = alloc::ffi::CString::new(name)?;
#[allow(unsafe_code)]
match unsafe { libc::if_nametoindex(ifname.as_ptr()) } {
0 => Err(anyhow::anyhow!(
"if_nametoindex: '{}'",
std::io::Error::last_os_error()
)),
otherwise => Ok(otherwise),
}
}
#[inline]
pub fn if_indextoname(index: u32) -> anyhow::Result<String> {
let mut buf = [0; libc::IF_NAMESIZE];
#[allow(unsafe_code)]
match unsafe { libc::if_indextoname(index, buf.as_mut_ptr()) } {
null if null.is_null() => Err(anyhow::anyhow!(
"if_indextoname: '{}'",
std::io::Error::last_os_error()
)),
_ => Ok(unsafe { std::ffi::CStr::from_ptr(buf.as_ptr()) }
.to_str()?
.to_owned()),
}
}
#[inline]
pub fn getpwuid(uid: libc::uid_t) -> anyhow::Result<std::path::PathBuf> {
#[allow(unsafe_code)]
let passwd = unsafe { libc::getpwuid(uid) };
#[allow(unsafe_code)]
if passwd.is_null() || unsafe { *passwd }.pw_dir.is_null() {
anyhow::bail!("getpwuid: '{}'", std::io::Error::last_os_error());
}
#[allow(unsafe_code)]
let buffer = unsafe { *passwd }.pw_dir;
#[allow(unsafe_code)]
Ok(unsafe { std::ffi::CStr::from_ptr(buffer) }.to_str()?.into())
}