Coverage Report

Created: 2025-09-04 06:37

/rust/registry/src/index.crates.io-6f17d22bba15001f/nix-0.27.1/src/sys/statvfs.rs
Line
Count
Source (jump to first uncovered line)
1
//! Get filesystem statistics
2
//!
3
//! See [the man pages](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html)
4
//! for more details.
5
use std::mem;
6
use std::os::unix::io::{AsFd, AsRawFd};
7
8
use libc::{self, c_ulong};
9
10
use crate::{errno::Errno, NixPath, Result};
11
12
#[cfg(not(target_os = "redox"))]
13
libc_bitflags!(
14
    /// File system mount Flags
15
    #[derive(Default)]
16
    pub struct FsFlags: c_ulong {
17
        /// Read Only
18
        #[cfg(not(target_os = "haiku"))]
19
        ST_RDONLY;
20
        /// Do not allow the set-uid bits to have an effect
21
        #[cfg(not(target_os = "haiku"))]
22
        ST_NOSUID;
23
        /// Do not interpret character or block-special devices
24
        #[cfg(any(target_os = "android", target_os = "linux"))]
25
        #[cfg_attr(docsrs, doc(cfg(all())))]
26
        ST_NODEV;
27
        /// Do not allow execution of binaries on the filesystem
28
        #[cfg(any(target_os = "android", target_os = "linux"))]
29
        #[cfg_attr(docsrs, doc(cfg(all())))]
30
        ST_NOEXEC;
31
        /// All IO should be done synchronously
32
        #[cfg(any(target_os = "android", target_os = "linux"))]
33
        #[cfg_attr(docsrs, doc(cfg(all())))]
34
        ST_SYNCHRONOUS;
35
        /// Allow mandatory locks on the filesystem
36
        #[cfg(any(target_os = "android", target_os = "linux"))]
37
        #[cfg_attr(docsrs, doc(cfg(all())))]
38
        ST_MANDLOCK;
39
        /// Write on file/directory/symlink
40
        #[cfg(target_os = "linux")]
41
        #[cfg_attr(docsrs, doc(cfg(all())))]
42
        ST_WRITE;
43
        /// Append-only file
44
        #[cfg(target_os = "linux")]
45
        #[cfg_attr(docsrs, doc(cfg(all())))]
46
        ST_APPEND;
47
        /// Immutable file
48
        #[cfg(target_os = "linux")]
49
        #[cfg_attr(docsrs, doc(cfg(all())))]
50
        ST_IMMUTABLE;
51
        /// Do not update access times on files
52
        #[cfg(any(target_os = "android", target_os = "linux"))]
53
        #[cfg_attr(docsrs, doc(cfg(all())))]
54
        ST_NOATIME;
55
        /// Do not update access times on files
56
        #[cfg(any(target_os = "android", target_os = "linux"))]
57
        #[cfg_attr(docsrs, doc(cfg(all())))]
58
        ST_NODIRATIME;
59
        /// Update access time relative to modify/change time
60
        #[cfg(any(target_os = "android", all(target_os = "linux", not(target_env = "musl"))))]
61
        #[cfg_attr(docsrs, doc(cfg(all())))]
62
        ST_RELATIME;
63
    }
64
);
65
66
/// Wrapper around the POSIX `statvfs` struct
67
///
68
/// For more information see the [`statvfs(3)` man pages](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_statvfs.h.html).
69
#[repr(transparent)]
70
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
71
pub struct Statvfs(libc::statvfs);
72
73
impl Statvfs {
74
    /// get the file system block size
75
0
    pub fn block_size(&self) -> c_ulong {
76
0
        self.0.f_bsize
77
0
    }
78
79
    /// Get the fundamental file system block size
80
0
    pub fn fragment_size(&self) -> c_ulong {
81
0
        self.0.f_frsize
82
0
    }
83
84
    /// Get the number of blocks.
85
    ///
86
    /// Units are in units of `fragment_size()`
87
0
    pub fn blocks(&self) -> libc::fsblkcnt_t {
88
0
        self.0.f_blocks
89
0
    }
90
91
    /// Get the number of free blocks in the file system
92
0
    pub fn blocks_free(&self) -> libc::fsblkcnt_t {
93
0
        self.0.f_bfree
94
0
    }
95
96
    /// Get the number of free blocks for unprivileged users
97
0
    pub fn blocks_available(&self) -> libc::fsblkcnt_t {
98
0
        self.0.f_bavail
99
0
    }
100
101
    /// Get the total number of file inodes
102
0
    pub fn files(&self) -> libc::fsfilcnt_t {
103
0
        self.0.f_files
104
0
    }
105
106
    /// Get the number of free file inodes
107
0
    pub fn files_free(&self) -> libc::fsfilcnt_t {
108
0
        self.0.f_ffree
109
0
    }
110
111
    /// Get the number of free file inodes for unprivileged users
112
0
    pub fn files_available(&self) -> libc::fsfilcnt_t {
113
0
        self.0.f_favail
114
0
    }
115
116
    /// Get the file system id
117
0
    pub fn filesystem_id(&self) -> c_ulong {
118
0
        self.0.f_fsid
119
0
    }
120
121
    /// Get the mount flags
122
    #[cfg(not(target_os = "redox"))]
123
    #[cfg_attr(docsrs, doc(cfg(all())))]
124
0
    pub fn flags(&self) -> FsFlags {
125
0
        FsFlags::from_bits_truncate(self.0.f_flag)
126
0
    }
127
128
    /// Get the maximum filename length
129
0
    pub fn name_max(&self) -> c_ulong {
130
0
        self.0.f_namemax
131
0
    }
132
}
133
134
/// Return a `Statvfs` object with information about the `path`
135
0
pub fn statvfs<P: ?Sized + NixPath>(path: &P) -> Result<Statvfs> {
136
0
    unsafe {
137
0
        Errno::clear();
138
0
        let mut stat = mem::MaybeUninit::<libc::statvfs>::uninit();
139
0
        let res = path.with_nix_path(|path| {
140
0
            libc::statvfs(path.as_ptr(), stat.as_mut_ptr())
141
0
        })?;
142
143
0
        Errno::result(res).map(|_| Statvfs(stat.assume_init()))
144
    }
145
0
}
146
147
/// Return a `Statvfs` object with information about `fd`
148
0
pub fn fstatvfs<Fd: AsFd>(fd: Fd) -> Result<Statvfs> {
149
0
    unsafe {
150
0
        Errno::clear();
151
0
        let mut stat = mem::MaybeUninit::<libc::statvfs>::uninit();
152
0
        Errno::result(libc::fstatvfs(fd.as_fd().as_raw_fd(), stat.as_mut_ptr()))
153
0
            .map(|_| Statvfs(stat.assume_init()))
154
0
    }
155
0
}
156
157
#[cfg(test)]
158
mod test {
159
    use crate::sys::statvfs::*;
160
    use std::fs::File;
161
162
    #[test]
163
    fn statvfs_call() {
164
        statvfs(&b"/"[..]).unwrap();
165
    }
166
167
    #[test]
168
    fn fstatvfs_call() {
169
        let root = File::open("/").unwrap();
170
        fstatvfs(&root).unwrap();
171
    }
172
}