13da5c369Sopenharmony_ci//! Get filesystem statistics 23da5c369Sopenharmony_ci//! 33da5c369Sopenharmony_ci//! See [the man pages](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html) 43da5c369Sopenharmony_ci//! for more details. 53da5c369Sopenharmony_ciuse std::mem; 63da5c369Sopenharmony_ciuse std::os::unix::io::AsRawFd; 73da5c369Sopenharmony_ci 83da5c369Sopenharmony_ciuse libc::{self, c_ulong}; 93da5c369Sopenharmony_ci 103da5c369Sopenharmony_ciuse crate::{errno::Errno, NixPath, Result}; 113da5c369Sopenharmony_ci 123da5c369Sopenharmony_ci#[cfg(not(target_os = "redox"))] 133da5c369Sopenharmony_cilibc_bitflags!( 143da5c369Sopenharmony_ci /// File system mount Flags 153da5c369Sopenharmony_ci #[repr(C)] 163da5c369Sopenharmony_ci #[derive(Default)] 173da5c369Sopenharmony_ci pub struct FsFlags: c_ulong { 183da5c369Sopenharmony_ci /// Read Only 193da5c369Sopenharmony_ci #[cfg(not(target_os = "haiku"))] 203da5c369Sopenharmony_ci ST_RDONLY; 213da5c369Sopenharmony_ci /// Do not allow the set-uid bits to have an effect 223da5c369Sopenharmony_ci #[cfg(not(target_os = "haiku"))] 233da5c369Sopenharmony_ci ST_NOSUID; 243da5c369Sopenharmony_ci /// Do not interpret character or block-special devices 253da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 263da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 273da5c369Sopenharmony_ci ST_NODEV; 283da5c369Sopenharmony_ci /// Do not allow execution of binaries on the filesystem 293da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 303da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 313da5c369Sopenharmony_ci ST_NOEXEC; 323da5c369Sopenharmony_ci /// All IO should be done synchronously 333da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 343da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 353da5c369Sopenharmony_ci ST_SYNCHRONOUS; 363da5c369Sopenharmony_ci /// Allow mandatory locks on the filesystem 373da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 383da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 393da5c369Sopenharmony_ci ST_MANDLOCK; 403da5c369Sopenharmony_ci /// Write on file/directory/symlink 413da5c369Sopenharmony_ci #[cfg(target_os = "linux")] 423da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 433da5c369Sopenharmony_ci ST_WRITE; 443da5c369Sopenharmony_ci /// Append-only file 453da5c369Sopenharmony_ci #[cfg(target_os = "linux")] 463da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 473da5c369Sopenharmony_ci ST_APPEND; 483da5c369Sopenharmony_ci /// Immutable file 493da5c369Sopenharmony_ci #[cfg(target_os = "linux")] 503da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 513da5c369Sopenharmony_ci ST_IMMUTABLE; 523da5c369Sopenharmony_ci /// Do not update access times on files 533da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 543da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 553da5c369Sopenharmony_ci ST_NOATIME; 563da5c369Sopenharmony_ci /// Do not update access times on files 573da5c369Sopenharmony_ci #[cfg(any(target_os = "android", target_os = "linux"))] 583da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 593da5c369Sopenharmony_ci ST_NODIRATIME; 603da5c369Sopenharmony_ci /// Update access time relative to modify/change time 613da5c369Sopenharmony_ci #[cfg(any(target_os = "android", all(target_os = "linux", not(any(target_env = "musl", target_env = "ohos")))))] 623da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 633da5c369Sopenharmony_ci ST_RELATIME; 643da5c369Sopenharmony_ci } 653da5c369Sopenharmony_ci); 663da5c369Sopenharmony_ci 673da5c369Sopenharmony_ci/// Wrapper around the POSIX `statvfs` struct 683da5c369Sopenharmony_ci/// 693da5c369Sopenharmony_ci/// For more information see the [`statvfs(3)` man pages](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_statvfs.h.html). 703da5c369Sopenharmony_ci#[repr(transparent)] 713da5c369Sopenharmony_ci#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 723da5c369Sopenharmony_cipub struct Statvfs(libc::statvfs); 733da5c369Sopenharmony_ci 743da5c369Sopenharmony_ciimpl Statvfs { 753da5c369Sopenharmony_ci /// get the file system block size 763da5c369Sopenharmony_ci pub fn block_size(&self) -> c_ulong { 773da5c369Sopenharmony_ci self.0.f_bsize 783da5c369Sopenharmony_ci } 793da5c369Sopenharmony_ci 803da5c369Sopenharmony_ci /// Get the fundamental file system block size 813da5c369Sopenharmony_ci pub fn fragment_size(&self) -> c_ulong { 823da5c369Sopenharmony_ci self.0.f_frsize 833da5c369Sopenharmony_ci } 843da5c369Sopenharmony_ci 853da5c369Sopenharmony_ci /// Get the number of blocks. 863da5c369Sopenharmony_ci /// 873da5c369Sopenharmony_ci /// Units are in units of `fragment_size()` 883da5c369Sopenharmony_ci pub fn blocks(&self) -> libc::fsblkcnt_t { 893da5c369Sopenharmony_ci self.0.f_blocks 903da5c369Sopenharmony_ci } 913da5c369Sopenharmony_ci 923da5c369Sopenharmony_ci /// Get the number of free blocks in the file system 933da5c369Sopenharmony_ci pub fn blocks_free(&self) -> libc::fsblkcnt_t { 943da5c369Sopenharmony_ci self.0.f_bfree 953da5c369Sopenharmony_ci } 963da5c369Sopenharmony_ci 973da5c369Sopenharmony_ci /// Get the number of free blocks for unprivileged users 983da5c369Sopenharmony_ci pub fn blocks_available(&self) -> libc::fsblkcnt_t { 993da5c369Sopenharmony_ci self.0.f_bavail 1003da5c369Sopenharmony_ci } 1013da5c369Sopenharmony_ci 1023da5c369Sopenharmony_ci /// Get the total number of file inodes 1033da5c369Sopenharmony_ci pub fn files(&self) -> libc::fsfilcnt_t { 1043da5c369Sopenharmony_ci self.0.f_files 1053da5c369Sopenharmony_ci } 1063da5c369Sopenharmony_ci 1073da5c369Sopenharmony_ci /// Get the number of free file inodes 1083da5c369Sopenharmony_ci pub fn files_free(&self) -> libc::fsfilcnt_t { 1093da5c369Sopenharmony_ci self.0.f_ffree 1103da5c369Sopenharmony_ci } 1113da5c369Sopenharmony_ci 1123da5c369Sopenharmony_ci /// Get the number of free file inodes for unprivileged users 1133da5c369Sopenharmony_ci pub fn files_available(&self) -> libc::fsfilcnt_t { 1143da5c369Sopenharmony_ci self.0.f_favail 1153da5c369Sopenharmony_ci } 1163da5c369Sopenharmony_ci 1173da5c369Sopenharmony_ci /// Get the file system id 1183da5c369Sopenharmony_ci pub fn filesystem_id(&self) -> c_ulong { 1193da5c369Sopenharmony_ci self.0.f_fsid 1203da5c369Sopenharmony_ci } 1213da5c369Sopenharmony_ci 1223da5c369Sopenharmony_ci /// Get the mount flags 1233da5c369Sopenharmony_ci #[cfg(not(target_os = "redox"))] 1243da5c369Sopenharmony_ci #[cfg_attr(docsrs, doc(cfg(all())))] 1253da5c369Sopenharmony_ci pub fn flags(&self) -> FsFlags { 1263da5c369Sopenharmony_ci FsFlags::from_bits_truncate(self.0.f_flag) 1273da5c369Sopenharmony_ci } 1283da5c369Sopenharmony_ci 1293da5c369Sopenharmony_ci /// Get the maximum filename length 1303da5c369Sopenharmony_ci pub fn name_max(&self) -> c_ulong { 1313da5c369Sopenharmony_ci self.0.f_namemax 1323da5c369Sopenharmony_ci } 1333da5c369Sopenharmony_ci} 1343da5c369Sopenharmony_ci 1353da5c369Sopenharmony_ci/// Return a `Statvfs` object with information about the `path` 1363da5c369Sopenharmony_cipub fn statvfs<P: ?Sized + NixPath>(path: &P) -> Result<Statvfs> { 1373da5c369Sopenharmony_ci unsafe { 1383da5c369Sopenharmony_ci Errno::clear(); 1393da5c369Sopenharmony_ci let mut stat = mem::MaybeUninit::<libc::statvfs>::uninit(); 1403da5c369Sopenharmony_ci let res = path.with_nix_path(|path| { 1413da5c369Sopenharmony_ci libc::statvfs(path.as_ptr(), stat.as_mut_ptr()) 1423da5c369Sopenharmony_ci })?; 1433da5c369Sopenharmony_ci 1443da5c369Sopenharmony_ci Errno::result(res).map(|_| Statvfs(stat.assume_init())) 1453da5c369Sopenharmony_ci } 1463da5c369Sopenharmony_ci} 1473da5c369Sopenharmony_ci 1483da5c369Sopenharmony_ci/// Return a `Statvfs` object with information about `fd` 1493da5c369Sopenharmony_cipub fn fstatvfs<T: AsRawFd>(fd: &T) -> Result<Statvfs> { 1503da5c369Sopenharmony_ci unsafe { 1513da5c369Sopenharmony_ci Errno::clear(); 1523da5c369Sopenharmony_ci let mut stat = mem::MaybeUninit::<libc::statvfs>::uninit(); 1533da5c369Sopenharmony_ci Errno::result(libc::fstatvfs(fd.as_raw_fd(), stat.as_mut_ptr())) 1543da5c369Sopenharmony_ci .map(|_| Statvfs(stat.assume_init())) 1553da5c369Sopenharmony_ci } 1563da5c369Sopenharmony_ci} 1573da5c369Sopenharmony_ci 1583da5c369Sopenharmony_ci#[cfg(test)] 1593da5c369Sopenharmony_cimod test { 1603da5c369Sopenharmony_ci use crate::sys::statvfs::*; 1613da5c369Sopenharmony_ci use std::fs::File; 1623da5c369Sopenharmony_ci 1633da5c369Sopenharmony_ci #[test] 1643da5c369Sopenharmony_ci fn statvfs_call() { 1653da5c369Sopenharmony_ci statvfs(&b"/"[..]).unwrap(); 1663da5c369Sopenharmony_ci } 1673da5c369Sopenharmony_ci 1683da5c369Sopenharmony_ci #[test] 1693da5c369Sopenharmony_ci fn fstatvfs_call() { 1703da5c369Sopenharmony_ci let root = File::open("/").unwrap(); 1713da5c369Sopenharmony_ci fstatvfs(&root).unwrap(); 1723da5c369Sopenharmony_ci } 1733da5c369Sopenharmony_ci} 174