fs4/
unix.rs

1macro_rules! lock_impl {
2    ($file: ty) => {
3        #[cfg(not(target_os = "wasi"))]
4        pub fn lock_shared(file: &$file) -> std::io::Result<()> {
5            flock(file, rustix::fs::FlockOperation::LockShared)
6        }
7
8        #[cfg(not(target_os = "wasi"))]
9        pub fn lock_exclusive(file: &$file) -> std::io::Result<()> {
10            flock(file, rustix::fs::FlockOperation::LockExclusive)
11        }
12
13        #[cfg(not(target_os = "wasi"))]
14        pub fn try_lock_shared(file: &$file) -> std::io::Result<bool> {
15            try_flock(file, rustix::fs::FlockOperation::NonBlockingLockShared)
16        }
17
18        #[cfg(not(target_os = "wasi"))]
19        pub fn try_lock_exclusive(file: &$file) -> std::io::Result<bool> {
20            try_flock(file, rustix::fs::FlockOperation::NonBlockingLockExclusive)
21        }
22
23        #[cfg(not(target_os = "wasi"))]
24        pub fn unlock(file: &$file) -> std::io::Result<()> {
25            flock(file, rustix::fs::FlockOperation::Unlock)
26        }
27
28        #[cfg(not(target_os = "wasi"))]
29        fn flock(file: &$file, flag: rustix::fs::FlockOperation) -> std::io::Result<()> {
30            let borrowed_fd = unsafe { rustix::fd::BorrowedFd::borrow_raw(file.as_raw_fd()) };
31
32            match rustix::fs::flock(borrowed_fd, flag) {
33                Ok(_) => Ok(()),
34                Err(e) => Err(std::io::Error::from_raw_os_error(e.raw_os_error())),
35            }
36        }
37
38        #[cfg(not(target_os = "wasi"))]
39        fn try_flock(file: &$file, flag: rustix::fs::FlockOperation) -> std::io::Result<bool> {
40            let borrowed_fd = unsafe { rustix::fd::BorrowedFd::borrow_raw(file.as_raw_fd()) };
41
42            match rustix::fs::flock(borrowed_fd, flag) {
43                Ok(_) => Ok(true),
44                Err(e) => {
45                    let err = std::io::Error::from_raw_os_error(e.raw_os_error());
46                    if let std::io::ErrorKind::WouldBlock = err.kind() {
47                        return Ok(false);
48                    }
49                    Err(err)
50                }
51            }
52        }
53    };
54}
55
56#[cfg(any(
57    feature = "smol",
58    feature = "async-std",
59    feature = "tokio",
60    feature = "fs-err-tokio"
61))]
62pub(crate) mod async_impl;
63#[cfg(any(feature = "sync", feature = "fs-err"))]
64pub(crate) mod sync_impl;
65
66use crate::FsStats;
67
68use std::io::{Error, Result};
69use std::path::Path;
70
71pub fn lock_error() -> Error {
72    Error::from_raw_os_error(rustix::io::Errno::WOULDBLOCK.raw_os_error())
73}
74
75pub fn statvfs(path: impl AsRef<Path>) -> Result<FsStats> {
76    match rustix::fs::statvfs(path.as_ref()) {
77        Ok(stat) => Ok(FsStats {
78            free_space: stat.f_frsize * stat.f_bfree,
79            available_space: stat.f_frsize * stat.f_bavail,
80            total_space: stat.f_frsize * stat.f_blocks,
81            allocation_granularity: stat.f_frsize,
82        }),
83        Err(e) => Err(std::io::Error::from_raw_os_error(e.raw_os_error())),
84    }
85}