/rust/registry/src/index.crates.io-1949cf8c6b5b557f/filetime-0.2.29/src/unix/utimes.rs
Line | Count | Source |
1 | | use crate::FileTime; |
2 | | use std::ffi::CString; |
3 | | use std::fs; |
4 | | use std::io; |
5 | | use std::os::unix::prelude::*; |
6 | | use std::path::Path; |
7 | | |
8 | 0 | fn get_times( |
9 | 0 | atime: Option<FileTime>, |
10 | 0 | mtime: Option<FileTime>, |
11 | 0 | current: impl FnOnce() -> io::Result<fs::Metadata>, |
12 | 0 | ) -> io::Result<Option<(FileTime, FileTime)>> { |
13 | 0 | let pair = match (atime, mtime) { |
14 | 0 | (Some(a), Some(b)) => (a, b), |
15 | 0 | (None, None) => return Ok(None), |
16 | 0 | (Some(a), None) => { |
17 | 0 | let meta = current()?; |
18 | 0 | (a, FileTime::from_last_modification_time(&meta)) |
19 | | } |
20 | 0 | (None, Some(b)) => { |
21 | 0 | let meta = current()?; |
22 | 0 | (FileTime::from_last_access_time(&meta), b) |
23 | | } |
24 | | }; |
25 | 0 | Ok(Some(pair)) |
26 | 0 | } |
27 | | |
28 | | #[allow(dead_code)] |
29 | 0 | pub fn set_symlink_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> { |
30 | 0 | set_times(p, Some(atime), Some(mtime), true) |
31 | 0 | } |
32 | | |
33 | 0 | pub fn set_times( |
34 | 0 | p: &Path, |
35 | 0 | atime: Option<FileTime>, |
36 | 0 | mtime: Option<FileTime>, |
37 | 0 | symlink: bool, |
38 | 0 | ) -> io::Result<()> { |
39 | 0 | let (atime, mtime) = match get_times(atime, mtime, || p.metadata())? { |
40 | 0 | Some(pair) => pair, |
41 | 0 | None => return Ok(()), |
42 | | }; |
43 | 0 | let p = CString::new(p.as_os_str().as_bytes())?; |
44 | 0 | let times = [to_timeval(&atime), to_timeval(&mtime)]; |
45 | 0 | let rc = unsafe { |
46 | 0 | if symlink { |
47 | 0 | libc::lutimes(p.as_ptr(), times.as_ptr()) |
48 | | } else { |
49 | 0 | libc::utimes(p.as_ptr(), times.as_ptr()) |
50 | | } |
51 | | }; |
52 | 0 | return if rc == 0 { |
53 | 0 | Ok(()) |
54 | | } else { |
55 | 0 | Err(io::Error::last_os_error()) |
56 | | }; |
57 | 0 | } |
58 | | |
59 | 0 | fn to_timeval(ft: &FileTime) -> libc::timeval { |
60 | 0 | libc::timeval { |
61 | 0 | tv_sec: ft.seconds() as libc::time_t, |
62 | 0 | tv_usec: (ft.nanoseconds() / 1000) as libc::suseconds_t, |
63 | 0 | } |
64 | 0 | } |
65 | | |
66 | | #[cfg(target_env = "uclibc")] |
67 | | fn to_timespec(ft: &FileTime) -> libc::timespec { |
68 | | libc::timespec { |
69 | | tv_sec: ft.seconds() as libc::time_t, |
70 | | #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] |
71 | | tv_nsec: (ft.nanoseconds()) as i64, |
72 | | #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] |
73 | | tv_nsec: (ft.nanoseconds()) as libc::c_long, |
74 | | } |
75 | | } |