diff options
Diffstat (limited to 'vendor/filetime/src/redox.rs')
-rw-r--r-- | vendor/filetime/src/redox.rs | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/vendor/filetime/src/redox.rs b/vendor/filetime/src/redox.rs new file mode 100644 index 0000000..b189ea5 --- /dev/null +++ b/vendor/filetime/src/redox.rs @@ -0,0 +1,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 +} |