1 use std::fmt::{self, Debug};
2 use std::mem;
3 use std::os::unix::io::AsRawFd;
4 #[cfg(not(any(target_os = "linux", target_os = "android")))]
5 use std::ffi::CStr;
6
7 use crate::{NixPath, Result, errno::Errno};
8
9 #[cfg(target_os = "android")]
10 pub type fsid_t = libc::__fsid_t;
11 #[cfg(not(target_os = "android"))]
12 pub type fsid_t = libc::fsid_t;
13
14 #[derive(Clone, Copy)]
15 #[repr(transparent)]
16 pub struct Statfs(libc::statfs);
17
18 #[cfg(target_os = "freebsd")]
19 type fs_type_t = u32;
20 #[cfg(target_os = "android")]
21 type fs_type_t = libc::c_ulong;
22 #[cfg(all(target_os = "linux", target_arch = "s390x"))]
23 type fs_type_t = libc::c_uint;
24 #[cfg(all(target_os = "linux", target_env = "musl"))]
25 type fs_type_t = libc::c_ulong;
26 #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
27 type fs_type_t = libc::__fsword_t;
28
29 #[cfg(any(
30 target_os = "freebsd",
31 target_os = "android",
32 all(target_os = "linux", target_arch = "s390x"),
33 all(target_os = "linux", target_env = "musl"),
34 all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))),
35 ))]
36 #[derive(Eq, Copy, Clone, PartialEq, Debug)]
37 pub struct FsType(pub fs_type_t);
38
39 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
40 pub const ADFS_SUPER_MAGIC: FsType = FsType(libc::ADFS_SUPER_MAGIC as fs_type_t);
41 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
42 pub const AFFS_SUPER_MAGIC: FsType = FsType(libc::AFFS_SUPER_MAGIC as fs_type_t);
43 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
44 pub const CODA_SUPER_MAGIC: FsType = FsType(libc::CODA_SUPER_MAGIC as fs_type_t);
45 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
46 pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC as fs_type_t);
47 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
48 pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC as fs_type_t);
49 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
50 pub const EXT2_SUPER_MAGIC: FsType = FsType(libc::EXT2_SUPER_MAGIC as fs_type_t);
51 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
52 pub const EXT3_SUPER_MAGIC: FsType = FsType(libc::EXT3_SUPER_MAGIC as fs_type_t);
53 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
54 pub const EXT4_SUPER_MAGIC: FsType = FsType(libc::EXT4_SUPER_MAGIC as fs_type_t);
55 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
56 pub const HPFS_SUPER_MAGIC: FsType = FsType(libc::HPFS_SUPER_MAGIC as fs_type_t);
57 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
58 pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC as fs_type_t);
59 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
60 pub const ISOFS_SUPER_MAGIC: FsType = FsType(libc::ISOFS_SUPER_MAGIC as fs_type_t);
61 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
62 pub const JFFS2_SUPER_MAGIC: FsType = FsType(libc::JFFS2_SUPER_MAGIC as fs_type_t);
63 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
64 pub const MINIX_SUPER_MAGIC: FsType = FsType(libc::MINIX_SUPER_MAGIC as fs_type_t);
65 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
66 pub const MINIX_SUPER_MAGIC2: FsType = FsType(libc::MINIX_SUPER_MAGIC2 as fs_type_t);
67 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
68 pub const MINIX2_SUPER_MAGIC: FsType = FsType(libc::MINIX2_SUPER_MAGIC as fs_type_t);
69 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
70 pub const MINIX2_SUPER_MAGIC2: FsType = FsType(libc::MINIX2_SUPER_MAGIC2 as fs_type_t);
71 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
72 pub const MSDOS_SUPER_MAGIC: FsType = FsType(libc::MSDOS_SUPER_MAGIC as fs_type_t);
73 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
74 pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC as fs_type_t);
75 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
76 pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC as fs_type_t);
77 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
78 pub const OPENPROM_SUPER_MAGIC: FsType = FsType(libc::OPENPROM_SUPER_MAGIC as fs_type_t);
79 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
80 pub const OVERLAYFS_SUPER_MAGIC: FsType = FsType(libc::OVERLAYFS_SUPER_MAGIC as fs_type_t);
81 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
82 pub const PROC_SUPER_MAGIC: FsType = FsType(libc::PROC_SUPER_MAGIC as fs_type_t);
83 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
84 pub const QNX4_SUPER_MAGIC: FsType = FsType(libc::QNX4_SUPER_MAGIC as fs_type_t);
85 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
86 pub const REISERFS_SUPER_MAGIC: FsType = FsType(libc::REISERFS_SUPER_MAGIC as fs_type_t);
87 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
88 pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC as fs_type_t);
89 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
90 pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC as fs_type_t);
91 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
92 pub const USBDEVICE_SUPER_MAGIC: FsType = FsType(libc::USBDEVICE_SUPER_MAGIC as fs_type_t);
93 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
94 pub const CGROUP_SUPER_MAGIC: FsType = FsType(libc::CGROUP_SUPER_MAGIC as fs_type_t);
95 #[cfg(all(target_os = "linux", not(target_env = "musl")))]
96 pub const CGROUP2_SUPER_MAGIC: FsType = FsType(libc::CGROUP2_SUPER_MAGIC as fs_type_t);
97
98
99 impl Statfs {
100 /// Magic code defining system type
101 #[cfg(not(any(
102 target_os = "openbsd",
103 target_os = "dragonfly",
104 target_os = "ios",
105 target_os = "macos"
106 )))]
filesystem_type(&self) -> FsType107 pub fn filesystem_type(&self) -> FsType {
108 FsType(self.0.f_type)
109 }
110
111 /// Magic code defining system type
112 #[cfg(not(any(target_os = "linux", target_os = "android")))]
filesystem_type_name(&self) -> &str113 pub fn filesystem_type_name(&self) -> &str {
114 let c_str = unsafe { CStr::from_ptr(self.0.f_fstypename.as_ptr()) };
115 c_str.to_str().unwrap()
116 }
117
118 /// Optimal transfer block size
119 #[cfg(any(target_os = "ios", target_os = "macos"))]
optimal_transfer_size(&self) -> i32120 pub fn optimal_transfer_size(&self) -> i32 {
121 self.0.f_iosize
122 }
123
124 /// Optimal transfer block size
125 #[cfg(target_os = "openbsd")]
optimal_transfer_size(&self) -> u32126 pub fn optimal_transfer_size(&self) -> u32 {
127 self.0.f_iosize
128 }
129
130 /// Optimal transfer block size
131 #[cfg(all(target_os = "linux", target_arch = "s390x"))]
optimal_transfer_size(&self) -> u32132 pub fn optimal_transfer_size(&self) -> u32 {
133 self.0.f_bsize
134 }
135
136 /// Optimal transfer block size
137 #[cfg(any(
138 target_os = "android",
139 all(target_os = "linux", target_env = "musl")
140 ))]
optimal_transfer_size(&self) -> libc::c_ulong141 pub fn optimal_transfer_size(&self) -> libc::c_ulong {
142 self.0.f_bsize
143 }
144
145 /// Optimal transfer block size
146 #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
optimal_transfer_size(&self) -> libc::__fsword_t147 pub fn optimal_transfer_size(&self) -> libc::__fsword_t {
148 self.0.f_bsize
149 }
150
151 /// Optimal transfer block size
152 #[cfg(target_os = "dragonfly")]
optimal_transfer_size(&self) -> libc::c_long153 pub fn optimal_transfer_size(&self) -> libc::c_long {
154 self.0.f_iosize
155 }
156
157 /// Optimal transfer block size
158 #[cfg(target_os = "freebsd")]
optimal_transfer_size(&self) -> u64159 pub fn optimal_transfer_size(&self) -> u64 {
160 self.0.f_iosize
161 }
162
163 /// Size of a block
164 #[cfg(any(target_os = "ios", target_os = "macos", target_os = "openbsd"))]
block_size(&self) -> u32165 pub fn block_size(&self) -> u32 {
166 self.0.f_bsize
167 }
168
169 /// Size of a block
170 // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
171 #[cfg(all(target_os = "linux", target_arch = "s390x"))]
block_size(&self) -> u32172 pub fn block_size(&self) -> u32 {
173 self.0.f_bsize
174 }
175
176 /// Size of a block
177 // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
178 #[cfg(all(target_os = "linux", target_env = "musl"))]
block_size(&self) -> libc::c_ulong179 pub fn block_size(&self) -> libc::c_ulong {
180 self.0.f_bsize
181 }
182
183 /// Size of a block
184 // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
185 #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
block_size(&self) -> libc::__fsword_t186 pub fn block_size(&self) -> libc::__fsword_t {
187 self.0.f_bsize
188 }
189
190 /// Size of a block
191 #[cfg(target_os = "freebsd")]
block_size(&self) -> u64192 pub fn block_size(&self) -> u64 {
193 self.0.f_bsize
194 }
195
196 /// Size of a block
197 #[cfg(target_os = "android")]
block_size(&self) -> libc::c_ulong198 pub fn block_size(&self) -> libc::c_ulong {
199 self.0.f_bsize
200 }
201
202 /// Size of a block
203 #[cfg(target_os = "dragonfly")]
block_size(&self) -> libc::c_long204 pub fn block_size(&self) -> libc::c_long {
205 self.0.f_bsize
206 }
207
208 /// Maximum length of filenames
209 #[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
maximum_name_length(&self) -> u32210 pub fn maximum_name_length(&self) -> u32 {
211 self.0.f_namemax
212 }
213
214 /// Maximum length of filenames
215 #[cfg(all(target_os = "linux", target_arch = "s390x"))]
maximum_name_length(&self) -> u32216 pub fn maximum_name_length(&self) -> u32 {
217 self.0.f_namelen
218 }
219
220 /// Maximum length of filenames
221 #[cfg(all(target_os = "linux", target_env = "musl"))]
maximum_name_length(&self) -> libc::c_ulong222 pub fn maximum_name_length(&self) -> libc::c_ulong {
223 self.0.f_namelen
224 }
225
226 /// Maximum length of filenames
227 #[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))))]
maximum_name_length(&self) -> libc::__fsword_t228 pub fn maximum_name_length(&self) -> libc::__fsword_t {
229 self.0.f_namelen
230 }
231
232 /// Maximum length of filenames
233 #[cfg(target_os = "android")]
maximum_name_length(&self) -> libc::c_ulong234 pub fn maximum_name_length(&self) -> libc::c_ulong {
235 self.0.f_namelen
236 }
237
238 /// Total data blocks in filesystem
239 #[cfg(any(
240 target_os = "ios",
241 target_os = "macos",
242 target_os = "android",
243 target_os = "freebsd",
244 target_os = "openbsd",
245 ))]
blocks(&self) -> u64246 pub fn blocks(&self) -> u64 {
247 self.0.f_blocks
248 }
249
250 /// Total data blocks in filesystem
251 #[cfg(target_os = "dragonfly")]
blocks(&self) -> libc::c_long252 pub fn blocks(&self) -> libc::c_long {
253 self.0.f_blocks
254 }
255
256 /// Total data blocks in filesystem
257 #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
blocks(&self) -> u64258 pub fn blocks(&self) -> u64 {
259 self.0.f_blocks
260 }
261
262 /// Total data blocks in filesystem
263 #[cfg(not(any(
264 target_os = "ios",
265 target_os = "macos",
266 target_os = "android",
267 target_os = "freebsd",
268 target_os = "openbsd",
269 target_os = "dragonfly",
270 all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
271 )))]
blocks(&self) -> libc::c_ulong272 pub fn blocks(&self) -> libc::c_ulong {
273 self.0.f_blocks
274 }
275
276 /// Free blocks in filesystem
277 #[cfg(any(
278 target_os = "ios",
279 target_os = "macos",
280 target_os = "android",
281 target_os = "freebsd",
282 target_os = "openbsd",
283 ))]
blocks_free(&self) -> u64284 pub fn blocks_free(&self) -> u64 {
285 self.0.f_bfree
286 }
287
288 /// Free blocks in filesystem
289 #[cfg(target_os = "dragonfly")]
blocks_free(&self) -> libc::c_long290 pub fn blocks_free(&self) -> libc::c_long {
291 self.0.f_bfree
292 }
293
294 /// Free blocks in filesystem
295 #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
blocks_free(&self) -> u64296 pub fn blocks_free(&self) -> u64 {
297 self.0.f_bfree
298 }
299
300 /// Free blocks in filesystem
301 #[cfg(not(any(
302 target_os = "ios",
303 target_os = "macos",
304 target_os = "android",
305 target_os = "freebsd",
306 target_os = "openbsd",
307 target_os = "dragonfly",
308 all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
309 )))]
blocks_free(&self) -> libc::c_ulong310 pub fn blocks_free(&self) -> libc::c_ulong {
311 self.0.f_bfree
312 }
313
314 /// Free blocks available to unprivileged user
315 #[cfg(any(target_os = "ios", target_os = "macos", target_os = "android"))]
blocks_available(&self) -> u64316 pub fn blocks_available(&self) -> u64 {
317 self.0.f_bavail
318 }
319
320 /// Free blocks available to unprivileged user
321 #[cfg(target_os = "dragonfly")]
blocks_available(&self) -> libc::c_long322 pub fn blocks_available(&self) -> libc::c_long {
323 self.0.f_bavail
324 }
325
326 /// Free blocks available to unprivileged user
327 #[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
blocks_available(&self) -> i64328 pub fn blocks_available(&self) -> i64 {
329 self.0.f_bavail
330 }
331
332 /// Free blocks available to unprivileged user
333 #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
blocks_available(&self) -> u64334 pub fn blocks_available(&self) -> u64 {
335 self.0.f_bavail
336 }
337
338 /// Free blocks available to unprivileged user
339 #[cfg(not(any(
340 target_os = "ios",
341 target_os = "macos",
342 target_os = "android",
343 target_os = "freebsd",
344 target_os = "openbsd",
345 target_os = "dragonfly",
346 all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
347 )))]
blocks_available(&self) -> libc::c_ulong348 pub fn blocks_available(&self) -> libc::c_ulong {
349 self.0.f_bavail
350 }
351
352 /// Total file nodes in filesystem
353 #[cfg(any(
354 target_os = "ios",
355 target_os = "macos",
356 target_os = "android",
357 target_os = "freebsd",
358 target_os = "openbsd",
359 ))]
files(&self) -> u64360 pub fn files(&self) -> u64 {
361 self.0.f_files
362 }
363
364 /// Total file nodes in filesystem
365 #[cfg(target_os = "dragonfly")]
files(&self) -> libc::c_long366 pub fn files(&self) -> libc::c_long {
367 self.0.f_files
368 }
369
370 /// Total file nodes in filesystem
371 #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
files(&self) -> libc::fsfilcnt_t372 pub fn files(&self) -> libc::fsfilcnt_t {
373 self.0.f_files
374 }
375
376 /// Total file nodes in filesystem
377 #[cfg(not(any(
378 target_os = "ios",
379 target_os = "macos",
380 target_os = "android",
381 target_os = "freebsd",
382 target_os = "openbsd",
383 target_os = "dragonfly",
384 all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
385 )))]
files(&self) -> libc::c_ulong386 pub fn files(&self) -> libc::c_ulong {
387 self.0.f_files
388 }
389
390 /// Free file nodes in filesystem
391 #[cfg(any(
392 target_os = "android",
393 target_os = "ios",
394 target_os = "macos",
395 target_os = "openbsd"
396 ))]
files_free(&self) -> u64397 pub fn files_free(&self) -> u64 {
398 self.0.f_ffree
399 }
400
401 /// Free file nodes in filesystem
402 #[cfg(target_os = "dragonfly")]
files_free(&self) -> libc::c_long403 pub fn files_free(&self) -> libc::c_long {
404 self.0.f_ffree
405 }
406
407 /// Free file nodes in filesystem
408 #[cfg(target_os = "freebsd")]
files_free(&self) -> i64409 pub fn files_free(&self) -> i64 {
410 self.0.f_ffree
411 }
412
413 /// Free file nodes in filesystem
414 #[cfg(all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32"))))]
files_free(&self) -> libc::fsfilcnt_t415 pub fn files_free(&self) -> libc::fsfilcnt_t {
416 self.0.f_ffree
417 }
418
419 /// Free file nodes in filesystem
420 #[cfg(not(any(
421 target_os = "ios",
422 target_os = "macos",
423 target_os = "android",
424 target_os = "freebsd",
425 target_os = "openbsd",
426 target_os = "dragonfly",
427 all(target_os = "linux", any(target_env = "musl", all(target_arch = "x86_64", target_pointer_width = "32")))
428 )))]
files_free(&self) -> libc::c_ulong429 pub fn files_free(&self) -> libc::c_ulong {
430 self.0.f_ffree
431 }
432
433 /// Filesystem ID
filesystem_id(&self) -> fsid_t434 pub fn filesystem_id(&self) -> fsid_t {
435 self.0.f_fsid
436 }
437 }
438
439 impl Debug for Statfs {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result440 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
441 f.debug_struct("Statfs")
442 .field("optimal_transfer_size", &self.optimal_transfer_size())
443 .field("block_size", &self.block_size())
444 .field("blocks", &self.blocks())
445 .field("blocks_free", &self.blocks_free())
446 .field("blocks_available", &self.blocks_available())
447 .field("files", &self.files())
448 .field("files_free", &self.files_free())
449 .field("filesystem_id", &self.filesystem_id())
450 .finish()
451 }
452 }
453
statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs>454 pub fn statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs> {
455 unsafe {
456 let mut stat = mem::MaybeUninit::<libc::statfs>::uninit();
457 let res = path.with_nix_path(|path| libc::statfs(path.as_ptr(), stat.as_mut_ptr()))?;
458 Errno::result(res).map(|_| Statfs(stat.assume_init()))
459 }
460 }
461
fstatfs<T: AsRawFd>(fd: &T) -> Result<Statfs>462 pub fn fstatfs<T: AsRawFd>(fd: &T) -> Result<Statfs> {
463 unsafe {
464 let mut stat = mem::MaybeUninit::<libc::statfs>::uninit();
465 Errno::result(libc::fstatfs(fd.as_raw_fd(), stat.as_mut_ptr()))
466 .map(|_| Statfs(stat.assume_init()))
467 }
468 }
469
470 #[cfg(test)]
471 mod test {
472 use std::fs::File;
473
474 use crate::sys::statfs::*;
475 use crate::sys::statvfs::*;
476 use std::path::Path;
477
478 #[test]
statfs_call()479 fn statfs_call() {
480 check_statfs("/tmp");
481 check_statfs("/dev");
482 check_statfs("/run");
483 check_statfs("/");
484 }
485
486 #[test]
fstatfs_call()487 fn fstatfs_call() {
488 check_fstatfs("/tmp");
489 check_fstatfs("/dev");
490 check_fstatfs("/run");
491 check_fstatfs("/");
492 }
493
check_fstatfs(path: &str)494 fn check_fstatfs(path: &str) {
495 if !Path::new(path).exists() {
496 return;
497 }
498 let vfs = statvfs(path.as_bytes()).unwrap();
499 let file = File::open(path).unwrap();
500 let fs = fstatfs(&file).unwrap();
501 assert_fs_equals(fs, vfs);
502 }
503
check_statfs(path: &str)504 fn check_statfs(path: &str) {
505 if !Path::new(path).exists() {
506 return;
507 }
508 let vfs = statvfs(path.as_bytes()).unwrap();
509 let fs = statfs(path.as_bytes()).unwrap();
510 assert_fs_equals(fs, vfs);
511 }
512
assert_fs_equals(fs: Statfs, vfs: Statvfs)513 fn assert_fs_equals(fs: Statfs, vfs: Statvfs) {
514 assert_eq!(fs.files() as u64, vfs.files() as u64);
515 assert_eq!(fs.blocks() as u64, vfs.blocks() as u64);
516 assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64);
517 }
518
519 // This test is ignored because files_free/blocks_free can change after statvfs call and before
520 // statfs call.
521 #[test]
522 #[ignore]
statfs_call_strict()523 fn statfs_call_strict() {
524 check_statfs_strict("/tmp");
525 check_statfs_strict("/dev");
526 check_statfs_strict("/run");
527 check_statfs_strict("/");
528 }
529
530 // This test is ignored because files_free/blocks_free can change after statvfs call and before
531 // fstatfs call.
532 #[test]
533 #[ignore]
fstatfs_call_strict()534 fn fstatfs_call_strict() {
535 check_fstatfs_strict("/tmp");
536 check_fstatfs_strict("/dev");
537 check_fstatfs_strict("/run");
538 check_fstatfs_strict("/");
539 }
540
check_fstatfs_strict(path: &str)541 fn check_fstatfs_strict(path: &str) {
542 if !Path::new(path).exists() {
543 return;
544 }
545 let vfs = statvfs(path.as_bytes());
546 let file = File::open(path).unwrap();
547 let fs = fstatfs(&file);
548 assert_fs_equals_strict(fs.unwrap(), vfs.unwrap())
549 }
550
check_statfs_strict(path: &str)551 fn check_statfs_strict(path: &str) {
552 if !Path::new(path).exists() {
553 return;
554 }
555 let vfs = statvfs(path.as_bytes());
556 let fs = statfs(path.as_bytes());
557 assert_fs_equals_strict(fs.unwrap(), vfs.unwrap())
558 }
559
assert_fs_equals_strict(fs: Statfs, vfs: Statvfs)560 fn assert_fs_equals_strict(fs: Statfs, vfs: Statvfs) {
561 assert_eq!(fs.files_free() as u64, vfs.files_free() as u64);
562 assert_eq!(fs.blocks_free() as u64, vfs.blocks_free() as u64);
563 assert_eq!(fs.blocks_available() as u64, vfs.blocks_available() as u64);
564 assert_eq!(fs.files() as u64, vfs.files() as u64);
565 assert_eq!(fs.blocks() as u64, vfs.blocks() as u64);
566 assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64);
567 }
568 }
569