use libc::mode_t;
use crate::fs::{file_type::FileType, permissions::FilePermissions};
pub(crate) struct FileAttr {
#[cfg(target_os = "linux")]
pub(crate) stat: libc::stat64,
#[cfg(target_os = "macos")]
pub(crate) stat: libc::stat,
#[cfg(target_os = "linux")]
pub(crate) statx_extra_fields: Option<StatxExtraFields>,
}
#[cfg(unix)]
impl FileAttr {
pub(crate) fn size(&self) -> u64 {
self.stat.st_size as u64
}
pub(crate) fn perm(&self) -> FilePermissions {
FilePermissions {
mode: (self.stat.st_mode as mode_t),
}
}
pub(crate) fn file_type(&self) -> FileType {
FileType {
mode: self.stat.st_mode as mode_t,
}
}
}
#[cfg(target_os = "linux")]
pub(crate) struct StatxExtraFields {
pub(crate) stx_mask: u32,
pub(crate) stx_btime: libc::statx_timestamp,
}
#[cfg(target_os = "linux")]
impl From<libc::statx> for FileAttr {
fn from(buf: libc::statx) -> Self {
let mut stat: libc::stat64 = unsafe { std::mem::zeroed() };
stat.st_dev = libc::makedev(buf.stx_dev_major, buf.stx_dev_minor) as _;
stat.st_ino = buf.stx_ino as libc::ino64_t;
stat.st_nlink = buf.stx_nlink as libc::nlink_t;
stat.st_mode = buf.stx_mode as libc::mode_t;
stat.st_uid = buf.stx_uid as libc::uid_t;
stat.st_gid = buf.stx_gid as libc::gid_t;
stat.st_rdev = libc::makedev(buf.stx_rdev_major, buf.stx_rdev_minor) as _;
stat.st_size = buf.stx_size as libc::off64_t;
stat.st_blksize = buf.stx_blksize as libc::blksize_t;
stat.st_blocks = buf.stx_blocks as libc::blkcnt64_t;
stat.st_atime = buf.stx_atime.tv_sec as libc::time_t;
stat.st_atime_nsec = buf.stx_atime.tv_nsec as _;
stat.st_mtime = buf.stx_mtime.tv_sec as libc::time_t;
stat.st_mtime_nsec = buf.stx_mtime.tv_nsec as _;
stat.st_ctime = buf.stx_ctime.tv_sec as libc::time_t;
stat.st_ctime_nsec = buf.stx_ctime.tv_nsec as _;
let extra = StatxExtraFields {
stx_mask: buf.stx_mask,
stx_btime: buf.stx_btime,
};
Self {
stat,
statx_extra_fields: Some(extra),
}
}
}
#[cfg(target_os = "macos")]
impl From<libc::stat> for FileAttr {
fn from(stat: libc::stat) -> Self {
Self { stat }
}
}