use super::file_metadata::file_metadata;
use crate::fs::{manually, open_beneath, FollowSymlinks, Metadata, OpenOptions};
use rustix::fs::OFlags;
use std::path::Path;
use std::{fs, io};
pub(crate) fn stat_impl(
start: &fs::File,
path: &Path,
follow: FollowSymlinks,
) -> io::Result<Metadata> {
use crate::fs::{stat_unchecked, OpenOptionsExt};
use std::path::Component;
if follow == FollowSymlinks::No {
let mut components = path.components();
if let Some(Component::Normal(component)) = components.next() {
if components.next().is_none() {
return stat_unchecked(start, component.as_ref(), FollowSymlinks::No);
}
}
}
let result = open_beneath(
start,
path,
OpenOptions::new()
.read(true)
.follow(follow)
.custom_flags(OFlags::PATH.bits() as i32),
);
match result {
Ok(file) => file_metadata(&file),
Err(err) => match rustix::io::Errno::from_io_error(&err) {
Some(rustix::io::Errno::NOSYS) => manually::stat(start, path, follow),
_ => Err(err),
},
}
}