1#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
2#[test]
3fn test_utimensat() {
4    use rustix::fs::{cwd, openat, statat, utimensat, AtFlags, Mode, OFlags, Timespec, Timestamps};
5
6    let tmp = tempfile::tempdir().unwrap();
7    let dir = openat(
8        cwd(),
9        tmp.path(),
10        OFlags::RDONLY | OFlags::CLOEXEC,
11        Mode::empty(),
12    )
13    .unwrap();
14
15    let _ = openat(
16        &dir,
17        "foo",
18        OFlags::CREATE | OFlags::WRONLY | OFlags::CLOEXEC,
19        Mode::empty(),
20    )
21    .unwrap();
22
23    let times = Timestamps {
24        last_access: Timespec {
25            tv_sec: 44000,
26            tv_nsec: 45000,
27        },
28        last_modification: Timespec {
29            tv_sec: 46000,
30            tv_nsec: 47000,
31        },
32    };
33    utimensat(&dir, "foo", &times, AtFlags::empty()).unwrap();
34
35    let after = statat(&dir, "foo", AtFlags::empty()).unwrap();
36
37    assert_eq!(times.last_modification.tv_sec as u64, after.st_mtime as u64);
38    #[cfg(not(target_os = "netbsd"))]
39    assert_eq!(
40        times.last_modification.tv_nsec as u64,
41        after.st_mtime_nsec as u64
42    );
43    #[cfg(target_os = "netbsd")]
44    assert_eq!(
45        times.last_modification.tv_nsec as u64,
46        after.st_mtimensec as u64
47    );
48    assert!(times.last_access.tv_sec as u64 >= after.st_atime as u64);
49    #[cfg(not(target_os = "netbsd"))]
50    assert!(
51        times.last_access.tv_sec as u64 > after.st_atime as u64
52            || times.last_access.tv_nsec as u64 >= after.st_atime_nsec as u64
53    );
54    #[cfg(target_os = "netbsd")]
55    assert!(
56        times.last_access.tv_sec as u64 > after.st_atime as u64
57            || times.last_access.tv_nsec as u64 >= after.st_atimensec as u64
58    );
59}
60
61#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
62#[test]
63fn test_utimensat_noent() {
64    use rustix::fs::{cwd, openat, utimensat, AtFlags, Mode, OFlags, Timespec, Timestamps};
65
66    let tmp = tempfile::tempdir().unwrap();
67    let dir = openat(
68        cwd(),
69        tmp.path(),
70        OFlags::RDONLY | OFlags::CLOEXEC,
71        Mode::empty(),
72    )
73    .unwrap();
74
75    let times = Timestamps {
76        last_access: Timespec {
77            tv_sec: 44000,
78            tv_nsec: 45000,
79        },
80        last_modification: Timespec {
81            tv_sec: 46000,
82            tv_nsec: 47000,
83        },
84    };
85    assert_eq!(
86        utimensat(&dir, "foo", &times, AtFlags::empty()).unwrap_err(),
87        rustix::io::Errno::NOENT
88    );
89}
90
91#[cfg(not(any(target_os = "redox", target_os = "wasi")))]
92#[test]
93fn test_utimensat_notdir() {
94    use rustix::fs::{cwd, openat, utimensat, AtFlags, Mode, OFlags, Timespec, Timestamps};
95
96    let tmp = tempfile::tempdir().unwrap();
97    let dir = openat(
98        cwd(),
99        tmp.path(),
100        OFlags::RDONLY | OFlags::CLOEXEC,
101        Mode::empty(),
102    )
103    .unwrap();
104
105    let foo = openat(
106        &dir,
107        "foo",
108        OFlags::CREATE | OFlags::WRONLY | OFlags::CLOEXEC,
109        Mode::empty(),
110    )
111    .unwrap();
112
113    let times = Timestamps {
114        last_access: Timespec {
115            tv_sec: 44000,
116            tv_nsec: 45000,
117        },
118        last_modification: Timespec {
119            tv_sec: 46000,
120            tv_nsec: 47000,
121        },
122    };
123    assert_eq!(
124        utimensat(&foo, "bar", &times, AtFlags::empty()).unwrap_err(),
125        rustix::io::Errno::NOTDIR
126    );
127}
128