1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
use crate::FileTime;
use std::fs::{self, File};
use std::io;
use std::os::unix::prelude::*;
use std::path::Path;
pub fn set_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
let fd = open_redox(p, 0).map_err(|err| io::Error::from_raw_os_error(err.errno))?;
let res = set_file_times_redox(fd, atime, mtime);
let _ = syscall::close(fd);
res
}
pub fn set_file_mtime(p: &Path, mtime: FileTime) -> io::Result<()> {
let fd = open_redox(p, 0).map_err(|err| io::Error::from_raw_os_error(err.errno))?;
let mut st = syscall::Stat::default();
let res = match syscall::fstat(fd, &mut st) {
Err(err) => Err(io::Error::from_raw_os_error(err.errno)),
Ok(_) => set_file_times_redox(
fd,
FileTime {
seconds: st.st_atime as i64,
nanos: st.st_atime_nsec as u32,
},
mtime,
),
};
let _ = syscall::close(fd);
res
}
pub fn set_file_atime(p: &Path, atime: FileTime) -> io::Result<()> {
let fd = open_redox(p, 0).map_err(|err| io::Error::from_raw_os_error(err.errno))?;
let mut st = syscall::Stat::default();
let res = match syscall::fstat(fd, &mut st) {
Err(err) => Err(io::Error::from_raw_os_error(err.errno)),
Ok(_) => set_file_times_redox(
fd,
atime,
FileTime {
seconds: st.st_mtime as i64,
nanos: st.st_mtime_nsec as u32,
},
),
};
let _ = syscall::close(fd);
res
}
pub fn set_symlink_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
let fd = open_redox(p, syscall::O_NOFOLLOW)
.map_err(|err| io::Error::from_raw_os_error(err.errno))?;
let res = set_file_times_redox(fd, atime, mtime);
let _ = syscall::close(fd);
res
}
pub fn set_file_handle_times(
f: &File,
atime: Option<FileTime>,
mtime: Option<FileTime>,
) -> io::Result<()> {
let (atime1, mtime1) = match (atime, mtime) {
(Some(a), Some(b)) => (a, b),
(None, None) => return Ok(()),
(Some(a), None) => {
let meta = f.metadata()?;
(a, FileTime::from_last_modification_time(&meta))
}
(None, Some(b)) => {
let meta = f.metadata()?;
(FileTime::from_last_access_time(&meta), b)
}
};
set_file_times_redox(f.as_raw_fd() as usize, atime1, mtime1)
}
fn open_redox(path: &Path, flags: usize) -> syscall::Result<usize> {
match path.to_str() {
Some(string) => syscall::open(string, flags),
None => Err(syscall::Error::new(syscall::EINVAL)),
}
}
fn set_file_times_redox(fd: usize, atime: FileTime, mtime: FileTime) -> io::Result<()> {
use syscall::TimeSpec;
fn to_timespec(ft: &FileTime) -> TimeSpec {
TimeSpec {
tv_sec: ft.seconds(),
tv_nsec: ft.nanoseconds() as i32,
}
}
let times = [to_timespec(&atime), to_timespec(&mtime)];
match syscall::futimens(fd, ×) {
Ok(_) => Ok(()),
Err(err) => Err(io::Error::from_raw_os_error(err.errno)),
}
}
pub fn from_last_modification_time(meta: &fs::Metadata) -> FileTime {
FileTime {
seconds: meta.mtime(),
nanos: meta.mtime_nsec() as u32,
}
}
pub fn from_last_access_time(meta: &fs::Metadata) -> FileTime {
FileTime {
seconds: meta.atime(),
nanos: meta.atime_nsec() as u32,
}
}
pub fn from_creation_time(_meta: &fs::Metadata) -> Option<FileTime> {
None
}
|