### statvfs Source: https://docs.rs/fs2/latest/fs2/fn.statvfs.html Get the stats of the file system containing the provided path. This function accepts any type that implements AsRef and returns a Result. ```APIDOC ## statvfs ### Description Get the stats of the file system containing the provided path. ### Signature pub fn statvfs

(path: P) -> Result where P: AsRef, ### Parameters - **path** (P) - Required - A path to a file or directory within the file system to query. The type P must implement AsRef. ### Return Value Returns a Result containing the file system statistics. The FsStats type provides information about the file system such as total space, available space, and free space. ### Example ```rust use fs2::statvfs; let stats = statvfs("/").unwrap(); println!("Total space: {} bytes", stats.total_space()); ``` ``` -------------------------------- ### Benchmark file creation Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Baseline benchmark for creating and removing a file. ```rust /// Benchmarks creating and removing a file. This is a baseline benchmark /// for comparing against the truncate and allocate benchmarks. #[bench] fn bench_file_create(b: &mut test::Bencher) { let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("file"); b.iter(|| { fs::OpenOptions::new() .read(true) .write(true) .create(true) .open(&path) .unwrap(); fs::remove_file(&path).unwrap(); }); } ``` -------------------------------- ### Benchmark file allocation Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Benchmarks the performance of creating a file and allocating 32MiB for it. ```rust /// Benchmarks creating a file, allocating 32MiB for it, and deleting it. #[bench] fn bench_file_allocate(b: &mut test::Bencher) { let size = 32 * 1024 * 1024; let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("file"); b.iter(|| { let file = fs::OpenOptions::new() ``` -------------------------------- ### Test file allocation Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Demonstrates allocating space for a file and verifying the allocated size and file length, including behavior during truncation. ```rust /// Tests file allocation. #[test] fn allocate() { let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("fs2"); let file = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap(); let blksize = allocation_granularity(&path).unwrap(); // New files are created with no allocated size. assert_eq!(0, file.allocated_size().unwrap()); assert_eq!(0, file.metadata().unwrap().len()); // Allocate space for the file, checking that the allocated size steps // up by block size, and the file length matches the allocated size. file.allocate(2 * blksize - 1).unwrap(); assert_eq!(2 * blksize, file.allocated_size().unwrap()); assert_eq!(2 * blksize - 1, file.metadata().unwrap().len()); // Truncate the file, checking that the allocated size steps down by // block size. file.set_len(blksize + 1).unwrap(); assert_eq!(2 * blksize, file.allocated_size().unwrap()); assert_eq!(blksize + 1, file.metadata().unwrap().len()); } ``` -------------------------------- ### Filesystem statistics functions Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Standalone functions to retrieve filesystem statistics for a given path. ```rust /// Get the stats of the file system containing the provided path. pub fn statvfs

(path: P) -> Result where P: AsRef { sys::statvfs(path.as_ref()) } /// Returns the number of free bytes in the file system containing the provided /// path. pub fn free_space

(path: P) -> Result where P: AsRef { statvfs(path).map(|stat| stat.free_space) } /// Returns the available space in bytes to non-priveleged users in the file /// system containing the provided path. pub fn available_space

(path: P) -> Result where P: AsRef { statvfs(path).map(|stat| stat.available_space) } /// Returns the total space in bytes in the file system containing the provided /// path. pub fn total_space

(path: P) -> Result where P: AsRef { statvfs(path).map(|stat| stat.total_space) } /// Returns the filesystem's disk space allocation granularity in bytes. /// The provided path may be for any file in the filesystem. /// /// On Posix, this is equivalent to the filesystem's block size. /// On Windows, this is equivalent to the filesystem's cluster size. pub fn allocation_granularity

(path: P) -> Result where P: AsRef { statvfs(path).map(|stat| stat.allocation_granularity) } ``` -------------------------------- ### Benchmark total_space Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Benchmarks the performance of the total_space method. ```rust #[bench] fn bench_total_space(b: &mut test::Bencher) { let tempdir = tempdir::TempDir::new("fs2").unwrap(); b.iter(|| { test::black_box(total_space(&tempdir.path()).unwrap()); }); } ``` -------------------------------- ### Benchmark file truncation Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Benchmarks the performance of creating a file, truncating it to 32MiB, and deleting it. ```rust /// Benchmarks creating a file, truncating it to 32MiB, and deleting it. #[bench] fn bench_file_truncate(b: &mut test::Bencher) { let size = 32 * 1024 * 1024; let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("file"); b.iter(|| { let file = fs::OpenOptions::new() .read(true) .write(true) .create(true) .open(&path) .unwrap(); file.set_len(size).unwrap(); fs::remove_file(&path).unwrap(); }); } ``` -------------------------------- ### available_space Source: https://docs.rs/fs2/latest/index.html Returns the available space in bytes to non-privileged users in the file system containing the provided path. ```APIDOC ## available_space ### Description Returns the available space in bytes to non-privileged users in the file system containing the provided path. ### Function available_space(path: impl AsRef) -> io::Result ### Parameters - **path** (impl AsRef) - Required - A path to any file in the filesystem. ### Returns - **io::Result** - The available space in bytes. ``` -------------------------------- ### available_space Source: https://docs.rs/fs2/latest/fs2 Returns the available space in bytes to non-privileged users in the file system containing the provided path. ```APIDOC ## available_space ### Description Returns the available space in bytes to non-privileged users in the file system containing the provided path. ### Function `available_space` ### Parameters - **path** (path) - Required - A path to any file in the filesystem. ### Returns - **u64** - The available space in bytes. ``` -------------------------------- ### available_space Source: https://docs.rs/fs2 Returns the available space in bytes to non-privileged users in the file system containing the provided path. ```APIDOC ## available_space ### Description Returns the available space in bytes to non-privileged users in the file system containing the provided path. ### Function available_space(path) ### Parameters - **path** - The path to any file in the filesystem. ### Returns - **u64** - The available space in bytes. ``` -------------------------------- ### Benchmark available_space Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Benchmarks the performance of the available_space method. ```rust #[bench] fn bench_available_space(b: &mut test::Bencher) { let tempdir = tempdir::TempDir::new("fs2").unwrap(); b.iter(|| { test::black_box(available_space(&tempdir.path()).unwrap()); }); } ``` -------------------------------- ### Benchmark free_space Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Benchmarks the performance of the free_space method. ```rust #[bench] fn bench_free_space(b: &mut test::Bencher) { let tempdir = tempdir::TempDir::new("fs2").unwrap(); b.iter(|| { test::black_box(free_space(&tempdir.path()).unwrap()); }); } ``` -------------------------------- ### allocation_granularity Source: https://docs.rs/fs2/latest/index.html Returns the filesystem's disk space allocation granularity in bytes. The provided path may be for any file in the filesystem. ```APIDOC ## allocation_granularity ### Description Returns the filesystem's disk space allocation granularity in bytes. The provided path may be for any file in the filesystem. ### Function allocation_granularity(path: impl AsRef) -> io::Result ### Parameters - **path** (impl AsRef) - Required - A path to any file in the filesystem. ### Returns - **io::Result** - The allocation granularity in bytes. ``` -------------------------------- ### allocation_granularity Source: https://docs.rs/fs2 Returns the filesystem's disk space allocation granularity in bytes. The provided path may be for any file in the filesystem. ```APIDOC ## allocation_granularity ### Description Returns the filesystem's disk space allocation granularity in bytes. The provided path may be for any file in the filesystem. ### Function allocation_granularity(path) ### Parameters - **path** - The path to any file in the filesystem. ### Returns - **u64** - The allocation granularity in bytes. ``` -------------------------------- ### allocation_granularity Source: https://docs.rs/fs2/latest/fs2 Returns the filesystem's disk space allocation granularity in bytes. The provided path may be for any file in the filesystem. ```APIDOC ## allocation_granularity ### Description Returns the filesystem's disk space allocation granularity in bytes. The provided path may be for any file in the filesystem. ### Function `allocation_granularity` ### Parameters - **path** (path) - Required - A path to any file in the filesystem. ### Returns - **u64** - The allocation granularity in bytes. ``` -------------------------------- ### Test filesystem space Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Checks the filesystem space methods to ensure total, free, and available space values are consistent. ```rust /// Checks filesystem space methods. #[test] fn filesystem_space() { let tempdir = tempdir::TempDir::new("fs2").unwrap(); let total_space = total_space(&tempdir.path()).unwrap(); let free_space = free_space(&tempdir.path()).unwrap(); let available_space = available_space(&tempdir.path()).unwrap(); assert!(total_space > free_space); assert!(total_space > available_space); assert!(available_space <= free_space); } ``` -------------------------------- ### FileExt::allocate Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Ensures that at least len bytes of disk space are allocated for the file, and the file size is at least len bytes. After a successful call, subsequent writes within the specified length are guaranteed not to fail due to lack of disk space. ```APIDOC ## FileExt::allocate ### Description Ensures that at least len bytes of disk space are allocated for the file, and the file size is at least len bytes. After a successful call to allocate, subsequent writes to the file within the specified length are guaranteed not to fail because of lack of disk space. ### Method fn allocate(&self, len: u64) -> Result<()> ### Parameters - len (u64) - Required - The number of bytes to allocate. ### Returns - Result<()> - Ok if allocation succeeded, otherwise an error. ``` -------------------------------- ### FsStats struct methods Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Methods for retrieving filesystem statistics from an FsStats instance. ```rust /// Returns the number of free bytes in the file system containing the provided /// path. pub fn free_space(&self) -> u64 { self.free_space } /// Returns the available space in bytes to non-priveleged users in the file /// system containing the provided path. pub fn available_space(&self) -> u64 { self.available_space } /// Returns the total space in bytes in the file system containing the provided /// path. pub fn total_space(&self) -> u64 { self.total_space } /// Returns the filesystem's disk space allocation granularity in bytes. /// The provided path may be for any file in the filesystem. /// /// On Posix, this is equivalent to the filesystem's block size. /// On Windows, this is equivalent to the filesystem's cluster size. pub fn allocation_granularity(&self) -> u64 { self.allocation_granularity } } ``` -------------------------------- ### fs2 unix.rs full source code Source: https://docs.rs/fs2/latest/src/fs2/unix.rs.html The complete source code of the unix.rs module from the fs2 crate. It defines public functions for file duplication, locking, unlocking, allocation, and statvfs, with platform-specific implementations for flock and allocate. Includes cfg attributes for different operating systems. ```rust extern crate libc; use std::ffi::CString; use std::fs::File; use std::io::{Error, ErrorKind, Result}; use std::mem; use std::os::unix::ffi::OsStrExt; use std::os::unix::fs::MetadataExt; use std::os::unix::io::{AsRawFd, FromRawFd}; use std::path::Path; use FsStats; pub fn duplicate(file: &File) -> Result { unsafe { let fd = libc::dup(file.as_raw_fd()); if fd < 0 { Err(Error::last_os_error()) } else { Ok(File::from_raw_fd(fd)) } } } pub fn lock_shared(file: &File) -> Result<()> { flock(file, libc::LOCK_SH) } pub fn lock_exclusive(file: &File) -> Result<()> { flock(file, libc::LOCK_EX) } pub fn try_lock_shared(file: &File) -> Result<()> { flock(file, libc::LOCK_SH | libc::LOCK_NB) } pub fn try_lock_exclusive(file: &File) -> Result<()> { flock(file, libc::LOCK_EX | libc::LOCK_NB) } pub fn unlock(file: &File) -> Result<()> { flock(file, libc::LOCK_UN) } pub fn lock_error() -> Error { Error::from_raw_os_error(libc::EWOULDBLOCK) } #[cfg(not(target_os = "solaris"))] fn flock(file: &File, flag: libc::c_int) -> Result<()> { let ret = unsafe { libc::flock(file.as_raw_fd(), flag) }; if ret < 0 { Err(Error::last_os_error()) } else { Ok(()) } } /// Simulate flock() using fcntl(); primarily for Oracle Solaris. #[cfg(target_os = "solaris")] fn flock(file: &File, flag: libc::c_int) -> Result<()> { let mut fl = libc::flock { l_whence: 0, l_start: 0, l_len: 0, l_type: 0, l_pad: [0; 4], l_pid: 0, l_sysid: 0, }; // In non-blocking mode, use F_SETLK for cmd, F_SETLKW otherwise, and don't forget to clear // LOCK_NB. let (cmd, operation) = match flag & libc::LOCK_NB { 0 => (libc::F_SETLKW, flag), _ => (libc::F_SETLK, flag & !libc::LOCK_NB), }; match operation { libc::LOCK_SH => fl.l_type |= libc::F_RDLCK, libc::LOCK_EX => fl.l_type |= libc::F_WRLCK, libc::LOCK_UN => fl.l_type |= libc::F_UNLCK, _ => return Err(Error::from_raw_os_error(libc::EINVAL)), } let ret = unsafe { libc::fcntl(file.as_raw_fd(), cmd, &fl) }; match ret { // Translate EACCES to EWOULDBLOCK -1 => match Error::last_os_error().raw_os_error() { Some(libc::EACCES) => return Err(lock_error()), _ => return Err(Error::last_os_error()) }, _ => Ok(()) } } pub fn allocated_size(file: &File) -> Result { file.metadata().map(|m| m.blocks() as u64 * 512) } #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "android", target_os = "nacl"))] pub fn allocate(file: &File, len: u64) -> Result<()> { let ret = unsafe { libc::posix_fallocate(file.as_raw_fd(), 0, len as libc::off_t) }; if ret == 0 { Ok(()) } else { Err(Error::last_os_error()) } } #[cfg(any(target_os = "macos", target_os = "ios"))] pub fn allocate(file: &File, len: u64) -> Result<()> { let stat = try!(file.metadata()); if len > stat.blocks() as u64 * 512 { let mut fstore = libc::fstore_t { fst_flags: libc::F_ALLOCATECONTIG, fst_posmode: libc::F_PEOFPOSMODE, fst_offset: 0, fst_length: len as libc::off_t, fst_bytesalloc: 0, }; let ret = unsafe { libc::fcntl(file.as_raw_fd(), libc::F_PREALLOCATE, &fstore) }; if ret == -1 { // Unable to allocate contiguous disk space; attempt to allocate non-contiguously. fstore.fst_flags = libc::F_ALLOCATEALL; let ret = unsafe { libc::fcntl(file.as_raw_fd(), libc::F_PREALLOCATE, &fstore) }; if ret == -1 { return Err(Error::last_os_error()); } } } if len > stat.size() as u64 { file.set_len(len) } else { Ok(()) } } #[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "dragonfly", target_os = "solaris", target_os = "haiku"))] pub fn allocate(file: &File, len: u64) -> Result<()> { // No file allocation API available, just set the length if necessary. if len > try!(file.metadata()).len() as u64 { file.set_len(len) } else { Ok(()) } } pub fn statvfs(path: &Path) -> Result { let cstr = match CString::new(path.as_os_str().as_bytes()) { Ok(cstr) => cstr, ``` -------------------------------- ### free_space Source: https://docs.rs/fs2/latest/fs2/fn.free_space.html Returns the number of free bytes in the file system containing the provided path. ```APIDOC ## free_space ### Description Returns the number of free bytes in the file system containing the provided path. ### Function Signature pub fn free_space

(path: P) -> Result where P: AsRef, ### Parameters - **path** (P) - Required - A path to a file or directory in the file system to query. ### Return Value - **Result** - The number of free bytes in the file system containing the path, or an error if the operation fails. ``` -------------------------------- ### total_space Source: https://docs.rs/fs2/latest/fs2/fn.total_space.html Returns the total space in bytes in the file system containing the provided path. ```APIDOC ## total_space ### Description Returns the total space in bytes in the file system containing the provided path. ### Function Signature ```rust pub fn total_space

(path: P) -> Result where P: AsRef, ``` ### Parameters - **path** (`P`) - Required - A path to any file or directory within the file system of interest. The type `P` must implement `AsRef`. ### Return Value - `Result` - On success, returns the total space in bytes of the file system containing the given path. On failure, returns an error. ``` -------------------------------- ### FsStats::allocation_granularity Source: https://docs.rs/fs2/latest/fs2/struct.FsStats.html Returns the filesystem's disk space allocation granularity in bytes. On Posix, this is equivalent to the filesystem's block size. On Windows, this is equivalent to the filesystem's cluster size. ```APIDOC ## FsStats::allocation_granularity ### Description Returns the filesystem's disk space allocation granularity in bytes. The provided path may be for any file in the filesystem. On Posix, this is equivalent to the filesystem's block size. On Windows, this is equivalent to the filesystem's cluster size. ### Method allocation_granularity ### Signature pub fn allocation_granularity(&self) -> u64 ### Parameters None ### Returns u64 - The filesystem's disk space allocation granularity in bytes. ``` -------------------------------- ### Test duplicate method creates new file descriptor Source: https://docs.rs/fs2/latest/src/fs2/unix.rs.html Verifies that the duplicate method returns a file with a new file descriptor. ```rust #[test] fn duplicate_new_fd() { let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("fs2"); let file1 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap(); let file2 = file1.duplicate().unwrap(); assert!(file1.as_raw_fd() != file2.as_raw_fd()); } ``` -------------------------------- ### FsStats::available_space Source: https://docs.rs/fs2/latest/fs2/struct.FsStats.html Returns the available space in bytes to non-privileged users in the file system containing the provided path. ```APIDOC ## FsStats::available_space ### Description Returns the available space in bytes to non-privileged users in the file system containing the provided path. ### Method available_space ### Signature pub fn available_space(&self) -> u64 ### Parameters None ### Returns u64 - The available space in bytes to non-privileged users. ``` -------------------------------- ### FileExt::unlock Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Unlocks the file. ```APIDOC ## FileExt::unlock ### Description Unlocks the file. ### Method fn unlock(&self) -> Result<()> ### Parameters None ### Returns - Result<()> - Ok if the unlock succeeded, otherwise an error. ``` -------------------------------- ### Benchmark duplicate Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Benchmarks the performance of duplicating a file descriptor or handle. ```rust #[bench] fn bench_duplicate(b: &mut test::Bencher) { let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("fs2"); let file = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap(); b.iter(|| test::black_box(file.duplicate().unwrap())); } ``` -------------------------------- ### Test file duplication Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Verifies that file duplication shares the file position. ```rust /// Tests file duplication. #[test] fn duplicate() { let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("fs2"); let mut file1 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap(); let mut file2 = file1.duplicate().unwrap(); // Write into the first file and then drop it. file1.write_all(b"foo").unwrap(); drop(file1); let mut buf = vec![]; // Read from the second file; since the position is shared it will already be at EOF. file2.read_to_end(&mut buf).unwrap(); assert_eq!(0, buf.len()); // Rewind and read. file2.seek(SeekFrom::Start(0)).unwrap(); file2.read_to_end(&mut buf).unwrap(); assert_eq!(&buf, &b"foo"); } ``` -------------------------------- ### FsStats methods Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Methods on the FsStats struct to access file system statistics fields. ```APIDOC ## FsStats methods ### Description Methods to retrieve individual file system statistics from an FsStats instance. ### Methods #### free_space - **Signature**: pub fn free_space(&self) -> u64 - **Description**: Returns the number of free bytes in the file system containing the provided path. #### available_space - **Signature**: pub fn available_space(&self) -> u64 - **Description**: Returns the available space in bytes to non-privileged users in the file system containing the provided path. #### total_space - **Signature**: pub fn total_space(&self) -> u64 - **Description**: Returns the total space in bytes in the file system containing the provided path. #### allocation_granularity - **Signature**: pub fn allocation_granularity(&self) -> u64 - **Description**: Returns the filesystem's disk space allocation granularity in bytes. On Posix, this is equivalent to the filesystem's block size; on Windows, this is equivalent to the filesystem's cluster size. ### Example ```rust let stats = statvfs("/some/path")?; let free = stats.free_space(); let available = stats.available_space(); let total = stats.total_space(); let granularity = stats.allocation_granularity(); ``` ``` -------------------------------- ### FileExt::duplicate Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Returns a duplicate instance of the file, sharing the same file position as the original. Implemented with dup(2) on Unix and DuplicateHandle on Windows. ```APIDOC ## FileExt::duplicate ### Description Returns a duplicate instance of the file. The returned file will share the same file position as the original file. If using rustc version 1.9 or later, prefer using File::try_clone to this. ### Method fn duplicate(&self) -> Result ### Parameters None ### Returns - Result - A duplicate file handle sharing the same file position. ``` -------------------------------- ### Test lock cleanup Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Verifies that a file lock is automatically released when the file handle that owns it is dropped. ```rust /// Tests that a lock is released after the file that owns it is dropped. #[test] fn lock_cleanup() { let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("fs2"); let file1 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap(); let file2 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap(); file1.lock_exclusive().unwrap(); assert_eq!(file2.try_lock_shared().unwrap_err().kind(), lock_contended_error().kind()); // Drop file1; the lock should be released. drop(file1); file2.lock_shared().unwrap(); } ``` -------------------------------- ### FsStats::free_space Source: https://docs.rs/fs2/latest/fs2/struct.FsStats.html Returns the number of free bytes in the file system containing the provided path. ```APIDOC ## FsStats::free_space ### Description Returns the number of free bytes in the file system containing the provided path. ### Method free_space ### Signature pub fn free_space(&self) -> u64 ### Parameters None ### Returns u64 - The number of free bytes in the file system. ``` -------------------------------- ### Retrieve Filesystem Statistics with statvfs Source: https://docs.rs/fs2/latest/src/fs2/unix.rs.html Uses the libc statvfs function to retrieve filesystem statistics. Note the cast to *const _ for platforms where c_char is not u8. ```rust unsafe { let mut stat: libc::statvfs = mem::zeroed(); // danburkert/fs2-rs#1: cast is necessary for platforms where c_char != u8. if libc::statvfs(cstr.as_ptr() as *const _, &mut stat) != 0 { Err(Error::last_os_error()) } else { Ok(FsStats { free_space: stat.f_frsize as u64 * stat.f_bfree as u64, available_space: stat.f_frsize as u64 * stat.f_bavail as u64, total_space: stat.f_frsize as u64 * stat.f_blocks as u64, allocation_granularity: stat.f_frsize as u64, }) } } ``` -------------------------------- ### Benchmark allocated_size Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Benchmarks the performance of retrieving the allocated size of a file after allocating 32MiB. ```rust #[bench] fn bench_allocated_size(b: &mut test::Bencher) { let size = 32 * 1024 * 1024; let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("file"); let file = fs::OpenOptions::new() .read(true) .write(true) .create(true) .open(&path) .unwrap(); file.allocate(size).unwrap(); b.iter(|| { file.allocated_size().unwrap(); }); } ``` -------------------------------- ### Benchmark lock_exclusive and unlock Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Benchmarks the performance of acquiring an exclusive file lock and subsequently unlocking it. ```rust #[bench] fn bench_lock_unlock(b: &mut test::Bencher) { let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("fs2"); let file = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap(); b.iter(|| { file.lock_exclusive().unwrap(); file.unlock().unwrap(); }); } ``` -------------------------------- ### FsStats::total_space Source: https://docs.rs/fs2/latest/fs2/struct.FsStats.html Returns the total space in bytes in the file system containing the provided path. ```APIDOC ## FsStats::total_space ### Description Returns the total space in bytes in the file system containing the provided path. ### Method total_space ### Signature pub fn total_space(&self) -> u64 ### Parameters None ### Returns u64 - The total space in bytes in the file system. ``` -------------------------------- ### FileExt::allocated_size Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Returns the amount of physical space allocated for a file. ```APIDOC ## FileExt::allocated_size ### Description Returns the amount of physical space allocated for a file. ### Method fn allocated_size(&self) -> Result ### Parameters None ### Returns - Result - The allocated size in bytes. ``` -------------------------------- ### Test shared file locks Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Verifies concurrent shared access and contention with exclusive locks. ```rust /// Tests shared file lock operations. #[test] fn lock_shared() { let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("fs2"); let file1 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap(); let file2 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap(); let file3 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap(); // Concurrent shared access is OK, but not shared and exclusive. file1.lock_shared().unwrap(); file2.lock_shared().unwrap(); assert_eq!(file3.try_lock_exclusive().unwrap_err().kind(), lock_contended_error().kind()); file1.unlock().unwrap(); assert_eq!(file3.try_lock_exclusive().unwrap_err().kind(), lock_contended_error().kind()); // Once all shared file locks are dropped, an exclusive lock may be created; file2.unlock().unwrap(); file3.lock_exclusive().unwrap(); } ``` -------------------------------- ### Test duplicate method preserves close on exec flag Source: https://docs.rs/fs2/latest/src/fs2/unix.rs.html Ensures that the duplicate method preserves the close on exec flag by comparing file flags. ```rust #[test] fn duplicate_cloexec() { fn flags(file: &File) -> libc::c_int { unsafe { libc::fcntl(file.as_raw_fd(), libc::F_GETFL, 0) } } let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("fs2"); let file1 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap(); let file2 = file1.duplicate().unwrap(); assert_eq!(flags(&file1), flags(&file2)); } ``` -------------------------------- ### FileExt::try_lock_shared Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Locks the file for shared usage, or returns an error if the file is currently locked (see lock_contended_error). ```APIDOC ## FileExt::try_lock_shared ### Description Locks the file for shared usage, or returns an error if the file is currently locked (see lock_contended_error). ### Method fn try_lock_shared(&self) -> Result<()> ### Parameters None ### Returns - Result<()> - Ok if the lock was acquired, otherwise an error. ``` -------------------------------- ### Test exclusive file locks Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Basic test for exclusive file lock operations. ```rust /// Tests exclusive file lock operations. #[test] fn lock_exclusive() { let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("fs2"); let file1 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap(); ``` -------------------------------- ### FileExt Trait Definition Source: https://docs.rs/fs2/latest/fs2/trait.FileExt.html The FileExt trait provides methods for file duplication, allocation, and locking. It is implemented for std::fs::File. ```APIDOC ## Trait FileExt ### Description Extension trait for `std::fs::File` which provides allocation, duplication and locking methods. ### Definition ```rust pub trait FileExt { // Required methods fn duplicate(&self) -> Result; fn allocated_size(&self) -> Result; fn allocate(&self, len: u64) -> Result<()>; fn lock_shared(&self) -> Result<()>; fn lock_exclusive(&self) -> Result<()>; fn try_lock_shared(&self) -> Result<()>; fn try_lock_exclusive(&self) -> Result<()>; fn unlock(&self) -> Result<()>; } ``` ### Notes on File Locks This library provides whole-file locks in both shared (read) and exclusive (read-write) varieties. File locks are a cross-platform hazard since the file lock APIs exposed by operating system kernels vary in subtle and not-so-subtle ways. The API exposed by this library can be safely used across platforms as long as the following rules are followed: - Multiple locks should not be created on an individual `File` instance concurrently. - Duplicated files should not be locked without great care. - Files to be locked should be opened with at least read or write permissions. - File locks may only be relied upon to be advisory. See the tests in `lib.rs` for cross-platform lock behavior that may be relied upon; see the tests in `unix.rs` and `windows.rs` for examples of platform-specific behavior. File locks are implemented with `flock(2)` on Unix and `LockFile` on Windows. ### Implementations on Foreign Types - `impl FileExt for File` ### Implementors - `File` ### Dyn Compatibility This trait **is** dyn compatible. ## Required Methods ### fn duplicate(&self) -> Result Returns a duplicate instance of the file. The returned file will share the same file position as the original file. If using rustc version 1.9 or later, prefer using `File::try_clone` to this. **Notes:** This is implemented with `dup(2)` on Unix and `DuplicateHandle` on Windows. ### fn allocated_size(&self) -> Result Returns the amount of physical space allocated for a file. ### fn allocate(&self, len: u64) -> Result<()> Ensures that at least `len` bytes of disk space are allocated for the file, and the file size is at least `len` bytes. After a successful call to `allocate`, subsequent writes to the file within the specified length are guaranteed not to fail because of lack of disk space. ### fn lock_shared(&self) -> Result<()> Locks the file for shared usage, blocking if the file is currently locked exclusively. ### fn lock_exclusive(&self) -> Result<()> Locks the file for exclusive usage, blocking if the file is currently locked. ### fn try_lock_shared(&self) -> Result<()> Locks the file for shared usage, or returns a an error if the file is currently locked (see `lock_contended_error`). ### fn try_lock_exclusive(&self) -> Result<()> Locks the file for shared usage, or returns a an error if the file is currently locked (see `lock_contended_error`). ### fn unlock(&self) -> Result<()> Unlocks the file. ``` -------------------------------- ### FileExt::try_lock_exclusive Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Locks the file for exclusive usage, or returns an error if the file is currently locked (see lock_contended_error). ```APIDOC ## FileExt::try_lock_exclusive ### Description Locks the file for exclusive usage, or returns an error if the file is currently locked (see lock_contended_error). ### Method fn try_lock_exclusive(&self) -> Result<()> ### Parameters None ### Returns - Result<()> - Ok if the lock was acquired, otherwise an error. ``` -------------------------------- ### FileExt::lock_shared Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Locks the file for shared usage, blocking if the file is currently locked exclusively. ```APIDOC ## FileExt::lock_shared ### Description Locks the file for shared usage, blocking if the file is currently locked exclusively. ### Method fn lock_shared(&self) -> Result<()> ### Parameters None ### Returns - Result<()> - Ok if the lock was acquired, otherwise an error. ``` -------------------------------- ### Test lock replacement behavior Source: https://docs.rs/fs2/latest/src/fs2/unix.rs.html Tests that locking a file descriptor will replace any existing locks held on the file descriptor. ```rust #[test] fn lock_replace() { let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("fs2"); let file1 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap(); let file2 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap(); // Creating a shared lock will drop an exclusive lock. file1.lock_exclusive().unwrap(); file1.lock_shared().unwrap(); file2.lock_shared().unwrap(); // Attempting to replace a shared lock with an exclusive lock will fail // with multiple lock holders, and remove the original shared lock. assert_eq!(file2.try_lock_exclusive().unwrap_err().raw_os_error(), lock_contended_error().raw_os_error()); file1.lock_shared().unwrap(); } ``` -------------------------------- ### FileExt::lock_exclusive Source: https://docs.rs/fs2/latest/src/fs2/lib.rs.html Locks the file for exclusive usage, blocking if the file is currently locked. ```APIDOC ## FileExt::lock_exclusive ### Description Locks the file for exclusive usage, blocking if the file is currently locked. ### Method fn lock_exclusive(&self) -> Result<()> ### Parameters None ### Returns - Result<()> - Ok if the lock was acquired, otherwise an error. ``` -------------------------------- ### lock_contended_error() Source: https://docs.rs/fs2/latest/fs2/fn.lock_contended_error.html Returns the error that a call to a try lock method on a contended file will return. ```APIDOC ## lock_contended_error() ### Description Returns the error that a call to a try lock method on a contended file will return. ### Function Signature ```rust pub fn lock_contended_error() -> Error ``` ### Returns - **Error** - The error that a try lock method returns when the file is contended. ``` -------------------------------- ### Test lock sharing among duplicated file descriptors Source: https://docs.rs/fs2/latest/src/fs2/unix.rs.html Tests that locks are shared among duplicated file descriptors. ```rust #[test] fn lock_duplicate() { let tempdir = tempdir::TempDir::new("fs2").unwrap(); let path = tempdir.path().join("fs2"); let file1 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap(); let file2 = file1.duplicate().unwrap(); let file3 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap(); // Create a lock through fd1, then replace it through fd2. file1.lock_shared().unwrap(); file2.lock_exclusive().unwrap(); assert_eq!(file3.try_lock_shared().unwrap_err().raw_os_error(), lock_contended_error().raw_os_error()); // Either of the file descriptors should be able to unlock. file1.unlock().unwrap(); file3.lock_shared().unwrap(); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.