Partially switch to File::set_times() from utime crate

This commit is contained in:
Damien Elmes 2024-10-15 23:00:38 +10:00
parent e77632d7b2
commit 743017b471
3 changed files with 24 additions and 5 deletions

View file

@ -35,6 +35,7 @@ pub enum FileOp {
Sync, Sync,
Metadata, Metadata,
DecodeUtf8Filename, DecodeUtf8Filename,
SetFileTimes,
/// For legacy errors without any context. /// For legacy errors without any context.
Unknown, Unknown,
} }
@ -61,6 +62,7 @@ impl FileIoError {
FileOp::Sync => "sync".into(), FileOp::Sync => "sync".into(),
FileOp::Metadata => "get metadata".into(), FileOp::Metadata => "get metadata".into(),
FileOp::DecodeUtf8Filename => "decode utf8 filename".into(), FileOp::DecodeUtf8Filename => "decode utf8 filename".into(),
FileOp::SetFileTimes => "set file times".into(),
}, },
self.path.to_string_lossy(), self.path.to_string_lossy(),
self.source self.source

View file

@ -4,6 +4,8 @@
mod error; mod error;
use std::fs::File; use std::fs::File;
use std::fs::FileTimes;
use std::fs::OpenOptions;
use std::io::Read; use std::io::Read;
use std::io::Seek; use std::io::Seek;
use std::path::Component; use std::path::Component;
@ -37,6 +39,13 @@ pub fn open_file(path: impl AsRef<Path>) -> Result<File> {
}) })
} }
pub fn open_file_ext(path: impl AsRef<Path>, options: OpenOptions) -> Result<File> {
options.open(&path).context(FileIoSnafu {
path: path.as_ref(),
op: FileOp::Open,
})
}
/// See [std::fs::write]. /// See [std::fs::write].
pub fn write_file(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> Result<()> { pub fn write_file(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> Result<()> {
std::fs::write(&path, contents).context(FileIoSnafu { std::fs::write(&path, contents).context(FileIoSnafu {
@ -44,6 +53,14 @@ pub fn write_file(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> Result<
op: FileOp::Write, op: FileOp::Write,
}) })
} }
/// See [File::set_times]. Note that this won't work on folders.
pub fn set_file_times(path: impl AsRef<Path>, times: FileTimes) -> Result<()> {
let file = open_file_ext(&path, OpenOptions::new().write(true).to_owned())?;
file.set_times(times).context(FileIoSnafu {
path: path.as_ref(),
op: FileOp::SetFileTimes,
})
}
/// See [std::fs::remove_file]. /// See [std::fs::remove_file].
#[allow(dead_code)] #[allow(dead_code)]

View file

@ -3,6 +3,7 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::fs; use std::fs;
use std::fs::FileTimes;
use std::io; use std::io;
use std::io::Read; use std::io::Read;
use std::path::Path; use std::path::Path;
@ -12,6 +13,7 @@ use std::time;
use anki_io::create_dir; use anki_io::create_dir;
use anki_io::open_file; use anki_io::open_file;
use anki_io::set_file_times;
use anki_io::write_file; use anki_io::write_file;
use anki_io::FileIoError; use anki_io::FileIoError;
use anki_io::FileIoSnafu; use anki_io::FileIoSnafu;
@ -345,11 +347,9 @@ where
fs::rename(&src_path, &dst_path)?; fs::rename(&src_path, &dst_path)?;
// mark it as modified, so we can expire it in the future // mark it as modified, so we can expire it in the future
let secs = time::SystemTime::now() let secs = time::SystemTime::now();
.duration_since(time::UNIX_EPOCH) let times = FileTimes::new().set_accessed(secs).set_modified(secs);
.unwrap() if let Err(err) = set_file_times(&dst_path, times) {
.as_secs() as i64;
if let Err(err) = utime::set_file_times(&dst_path, secs, secs) {
// The libc utimes() call fails on (some? all?) Android devices. Since we don't // The libc utimes() call fails on (some? all?) Android devices. Since we don't
// do automatic expiry yet, we can safely ignore the error. // do automatic expiry yet, we can safely ignore the error.
if !cfg!(target_os = "android") { if !cfg!(target_os = "android") {