Coverage Report

Created: 2026-07-14 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/filetime-0.2.29/src/unix/linux.rs
Line
Count
Source
1
//! On Linux we try to use the more accurate `utimensat` syscall but this isn't
2
//! always available so we also fall back to `utimes` if we couldn't find
3
//! `utimensat` at runtime.
4
5
use crate::FileTime;
6
use std::ffi::CString;
7
use std::io;
8
use std::os::unix::prelude::*;
9
use std::path::Path;
10
use std::sync::atomic::AtomicBool;
11
use std::sync::atomic::Ordering::SeqCst;
12
13
0
pub fn set_symlink_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
14
0
    set_times(p, Some(atime), Some(mtime), true)
15
0
}
16
17
0
fn set_times(
18
0
    p: &Path,
19
0
    atime: Option<FileTime>,
20
0
    mtime: Option<FileTime>,
21
0
    symlink: bool,
22
0
) -> io::Result<()> {
23
0
    let flags = if symlink {
24
0
        libc::AT_SYMLINK_NOFOLLOW
25
    } else {
26
0
        0
27
    };
28
29
    // Same as the `if` statement above.
30
    static INVALID: AtomicBool = AtomicBool::new(false);
31
0
    if !INVALID.load(SeqCst) {
32
0
        let p = CString::new(p.as_os_str().as_bytes())?;
33
0
        let times = [super::to_timespec(&atime), super::to_timespec(&mtime)];
34
0
        let rc = unsafe { libc::utimensat(libc::AT_FDCWD, p.as_ptr(), times.as_ptr(), flags) };
35
0
        if rc == 0 {
36
0
            return Ok(());
37
0
        }
38
0
        let err = io::Error::last_os_error();
39
0
        if err.raw_os_error() == Some(libc::ENOSYS) {
40
0
            INVALID.store(true, SeqCst);
41
0
        } else {
42
0
            return Err(err);
43
        }
44
0
    }
45
46
0
    super::utimes::set_times(p, atime, mtime, symlink)
47
0
}