use crate::fs::OpenOptionsExt;
use crate::fs::{
errors, open, read_link_unchecked, set_times_follow_unchecked, OpenOptions, SystemTimeSpec,
};
use io_lifetimes::{AsFd, AsFilelike};
use rustix::fs::{chmodat, AtFlags, Mode, OFlags, RawMode};
use rustix::path::DecInt;
use rustix_linux_procfs::proc_self_fd;
use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf};
use std::{fs, io};
pub(crate) fn get_path_from_proc_self_fd(file: &fs::File) -> io::Result<PathBuf> {
read_link_unchecked(
&proc_self_fd()?.as_filelike_view::<fs::File>(),
DecInt::from_fd(file).as_ref(),
PathBuf::new(),
)
}
pub(crate) fn set_permissions_through_proc_self_fd(
start: &fs::File,
path: &Path,
perm: fs::Permissions,
) -> io::Result<()> {
let opath = open(
start,
path,
OpenOptions::new()
.read(true)
.custom_flags(OFlags::PATH.bits() as i32),
)?;
let dirfd = proc_self_fd()?;
let mode = Mode::from_bits(perm.mode() as RawMode).ok_or_else(errors::invalid_flags)?;
Ok(chmodat(
dirfd,
DecInt::from_fd(&opath),
mode,
AtFlags::empty(),
)?)
}
pub(crate) fn set_times_through_proc_self_fd(
start: &fs::File,
path: &Path,
atime: Option<SystemTimeSpec>,
mtime: Option<SystemTimeSpec>,
) -> io::Result<()> {
let opath = open(
start,
path,
OpenOptions::new()
.read(true)
.custom_flags(OFlags::PATH.bits() as i32),
)?;
set_times_follow_unchecked(
proc_self_fd()?.as_fd(),
DecInt::from_fd(&opath).as_ref(),
atime,
mtime,
)
}