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