1 use crate::FileTime;
2 use libc::{time_t, timespec};
3 use std::fs;
4 use std::os::unix::prelude::*;
5
6 cfg_if::cfg_if! {
7 if #[cfg(target_os = "linux")] {
8 mod utimes;
9 mod linux;
10 pub use self::linux::*;
11 } else if #[cfg(target_os = "android")] {
12 mod android;
13 pub use self::android::*;
14 } else if #[cfg(target_os = "macos")] {
15 mod utimes;
16 mod macos;
17 pub use self::macos::*;
18 } else if #[cfg(any(target_os = "solaris",
19 target_os = "illumos",
20 target_os = "emscripten",
21 target_os = "freebsd",
22 target_os = "netbsd",
23 target_os = "openbsd",
24 target_os = "haiku"))] {
25 mod utimensat;
26 pub use self::utimensat::*;
27 } else {
28 mod utimes;
29 pub use self::utimes::*;
30 }
31 }
32
33 #[allow(dead_code)]
to_timespec(ft: &Option<FileTime>) -> timespec34 fn to_timespec(ft: &Option<FileTime>) -> timespec {
35 cfg_if::cfg_if! {
36 if #[cfg(target_os = "macos")] {
37 // https://github.com/apple/darwin-xnu/blob/a449c6a3b8014d9406c2ddbdc81795da24aa7443/bsd/sys/stat.h#L541
38 const UTIME_OMIT: i64 = -2;
39 } else if #[cfg(target_os = "openbsd")] {
40 // https://github.com/openbsd/src/blob/master/sys/sys/stat.h#L189
41 const UTIME_OMIT: i64 = -1;
42 } else {
43 const UTIME_OMIT: i64 = 1_073_741_822;
44 }
45 }
46
47 if let &Some(ft) = ft {
48 timespec {
49 tv_sec: ft.seconds() as time_t,
50 tv_nsec: ft.nanoseconds() as _,
51 }
52 } else {
53 timespec {
54 tv_sec: 0,
55 tv_nsec: UTIME_OMIT as _,
56 }
57 }
58 }
59
from_last_modification_time(meta: &fs::Metadata) -> FileTime60 pub fn from_last_modification_time(meta: &fs::Metadata) -> FileTime {
61 FileTime {
62 seconds: meta.mtime(),
63 nanos: meta.mtime_nsec() as u32,
64 }
65 }
66
from_last_access_time(meta: &fs::Metadata) -> FileTime67 pub fn from_last_access_time(meta: &fs::Metadata) -> FileTime {
68 FileTime {
69 seconds: meta.atime(),
70 nanos: meta.atime_nsec() as u32,
71 }
72 }
73
from_creation_time(meta: &fs::Metadata) -> Option<FileTime>74 pub fn from_creation_time(meta: &fs::Metadata) -> Option<FileTime> {
75 macro_rules! birthtim {
76 ($(($e:expr, $i:ident)),*) => {
77 #[cfg(any($(target_os = $e),*))]
78 fn imp(meta: &fs::Metadata) -> Option<FileTime> {
79 $(
80 #[cfg(target_os = $e)]
81 use std::os::$i::fs::MetadataExt;
82 )*
83 Some(FileTime {
84 seconds: meta.st_birthtime(),
85 nanos: meta.st_birthtime_nsec() as u32,
86 })
87 }
88
89 #[cfg(all($(not(target_os = $e)),*))]
90 fn imp(_meta: &fs::Metadata) -> Option<FileTime> {
91 None
92 }
93 }
94 }
95
96 birthtim! {
97 ("bitrig", bitrig),
98 ("freebsd", freebsd),
99 ("ios", ios),
100 ("macos", macos),
101 ("openbsd", openbsd)
102 }
103
104 imp(meta)
105 }
106