#[cfg(all(target_os = "linux", any(target_env = "gnu", musl_v1_2_3)))]
use std::ffi::CString;
use crate::fs::Metadata;
#[cfg(all(target_os = "linux", any(target_env = "gnu", musl_v1_2_3)))]
use crate::op::Op;
#[cfg(all(target_os = "linux", any(target_env = "gnu", musl_v1_2_3)))]
pub async fn metadata(path: impl AsRef<std::path::Path>) -> std::io::Result<Metadata> {
let path = path.as_ref();
let driver = crate::executor::current_driver();
if driver.as_ref().is_some_and(|d| d.supports_completion()) {
let path_cstr = CString::new(path.as_os_str().as_encoded_bytes()).map_err(|e| {
std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("Invalid path: {}", e),
)
})?;
let driver = driver.expect("invalid driver state");
let mut op = crate::op::StatxOp::new(libc::AT_FDCWD, path_cstr, 0, libc::STATX_ALL);
let statx = std::future::poll_fn(move |cx| op.poll_completion(cx, &driver)).await?;
Ok(Metadata::from_statx(statx))
} else if crate::executor::offload_fs() {
let path = path.to_owned();
Ok(Metadata::from_std(
crate::spawn_blocking(move || std::fs::metadata(path))
.await
.map_err(|_| crate::fs::file::blocking_pool_io_error())??,
))
} else {
Ok(Metadata::from_std(std::fs::metadata(path)?))
}
}
#[cfg(not(all(target_os = "linux", any(target_env = "gnu", musl_v1_2_3))))]
pub async fn metadata(path: impl AsRef<std::path::Path>) -> std::io::Result<Metadata> {
if crate::executor::offload_fs() {
let path = path.as_ref().to_owned();
Ok(Metadata::from_std(
crate::spawn_blocking(move || std::fs::metadata(path))
.await
.map_err(|_| crate::fs::file::blocking_pool_io_error())??,
))
} else {
Ok(Metadata::from_std(std::fs::metadata(path)?))
}
}
#[cfg(all(target_os = "linux", any(target_env = "gnu", musl_v1_2_3)))]
pub async fn symlink_metadata(path: impl AsRef<std::path::Path>) -> std::io::Result<Metadata> {
let path = path.as_ref();
let driver = crate::executor::current_driver();
if driver.as_ref().is_some_and(|d| d.supports_completion()) {
let path_cstr = CString::new(path.as_os_str().as_encoded_bytes()).map_err(|e| {
std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("Invalid path: {}", e),
)
})?;
let driver = driver.expect("invalid driver state");
let mut op = crate::op::StatxOp::new(
libc::AT_FDCWD,
path_cstr,
libc::AT_SYMLINK_NOFOLLOW,
libc::STATX_ALL,
);
let statx = std::future::poll_fn(move |cx| op.poll_completion(cx, &driver)).await?;
Ok(Metadata::from_statx(statx))
} else if crate::executor::offload_fs() {
let path = path.to_owned();
Ok(Metadata::from_std(
crate::spawn_blocking(move || std::fs::symlink_metadata(path))
.await
.map_err(|_| crate::fs::file::blocking_pool_io_error())??,
))
} else {
Ok(Metadata::from_std(std::fs::symlink_metadata(path)?))
}
}
#[cfg(not(all(target_os = "linux", any(target_env = "gnu", musl_v1_2_3))))]
pub async fn symlink_metadata(path: impl AsRef<std::path::Path>) -> std::io::Result<Metadata> {
if crate::executor::offload_fs() {
let path = path.as_ref().to_owned();
Ok(Metadata::from_std(
crate::spawn_blocking(move || std::fs::symlink_metadata(path))
.await
.map_err(|_| crate::fs::file::blocking_pool_io_error())??,
))
} else {
Ok(Metadata::from_std(std::fs::symlink_metadata(path)?))
}
}