use super::File;
use crate::io::{SharedFd, cstr};
use crate::runtime::driver::op::Op;
use std::{ffi::CString, io, path::Path};
impl File {
pub async fn statx(&self) -> io::Result<libc::statx> {
let flags = libc::AT_EMPTY_PATH;
let mask = libc::STATX_ALL;
Op::statx(Some(self.fd.clone()), None, flags, mask)?.await
}
pub fn statx_builder(&self) -> StatxBuilder {
StatxBuilder {
file: Some(self.fd.clone()),
path: None,
flags: libc::AT_EMPTY_PATH,
mask: libc::STATX_ALL,
}
}
}
pub async fn statx<P: AsRef<Path>>(path: P) -> io::Result<libc::statx> {
StatxBuilder::new().pathname(path).unwrap().statx().await
}
pub struct StatxBuilder {
file: Option<SharedFd>,
path: Option<CString>,
flags: i32,
mask: u32,
}
impl Default for StatxBuilder {
fn default() -> Self {
Self::new()
}
}
impl StatxBuilder {
#[must_use]
pub fn new() -> StatxBuilder {
StatxBuilder {
file: None,
path: None,
flags: libc::AT_EMPTY_PATH,
mask: libc::STATX_ALL,
}
}
#[must_use]
pub fn dirfd(&mut self, file: &File) -> &mut Self {
self.file = Some(file.fd.clone());
self
}
pub fn pathname<P: AsRef<Path>>(&mut self, path: P) -> io::Result<&mut Self> {
self.path = Some(cstr(path.as_ref())?);
Ok(self)
}
#[must_use]
pub fn flags(&mut self, flags: i32) -> &mut Self {
self.flags = flags;
self
}
#[must_use]
pub fn mask(&mut self, mask: u32) -> &mut Self {
self.mask = mask;
self
}
pub async fn statx(&mut self) -> io::Result<libc::statx> {
let fd = self.file.take();
let path = self.path.take();
Op::statx(fd, path, self.flags, self.mask)?.await
}
}
#[allow(dead_code)]
pub async fn is_dir_regfile<P: AsRef<Path>>(path: P) -> (bool, bool) {
let mut builder = crate::fs::StatxBuilder::new();
if builder.mask(libc::STATX_TYPE).pathname(path).is_err() {
return (false, false);
}
let res = builder.statx().await;
match res {
Ok(statx) => (
(u32::from(statx.stx_mode) & libc::S_IFMT) == libc::S_IFDIR,
(u32::from(statx.stx_mode) & libc::S_IFMT) == libc::S_IFREG,
),
Err(_) => (false, false),
}
}