mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Added safe_rename and tests for cross-device file moves (OS error 18)
This commit is contained in:
parent
539054c34d
commit
e067c2858f
1 changed files with 31 additions and 1 deletions
|
@ -320,6 +320,18 @@ pub(crate) fn mtime_as_i64<P: AsRef<Path>>(path: P) -> io::Result<i64> {
|
|||
.as_millis() as i64)
|
||||
}
|
||||
|
||||
pub(crate) fn safe_rename(src: &Path, dst: &Path) -> io::Result<()> {
|
||||
match fs::rename(src, dst) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) if e.raw_os_error() == Some(18) => {
|
||||
fs::copy(src, dst)?;
|
||||
fs::remove_file(src)?;
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_files<S>(media_folder: &Path, files: &[S]) -> Result<()>
|
||||
where
|
||||
S: AsRef<str> + std::fmt::Debug,
|
||||
|
@ -344,7 +356,7 @@ where
|
|||
}
|
||||
|
||||
// move file to trash, clobbering any existing file with the same name
|
||||
fs::rename(&src_path, &dst_path)?;
|
||||
safe_rename(&src_path, &dst_path)?;
|
||||
|
||||
// mark it as modified, so we can expire it in the future
|
||||
let secs = time::SystemTime::now();
|
||||
|
@ -437,6 +449,8 @@ pub(crate) fn data_for_file(media_folder: &Path, fname: &str) -> Result<Option<V
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::borrow::Cow;
|
||||
use std::fs;
|
||||
use super::safe_rename;
|
||||
|
||||
use tempfile::tempdir;
|
||||
|
||||
|
@ -550,4 +564,20 @@ mod test {
|
|||
Cow::<str>::Owned(format!("{}_", " ".repeat(MAX_MEDIA_FILENAME_LENGTH - 2)))
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn safe_rename_moves_file() {
|
||||
let dir = tempdir().unwrap();
|
||||
let src = dir.path().join("test_src.txt");
|
||||
let dst = dir.path().join("test_dst.txt");
|
||||
|
||||
fs::write(&src, b"hello world").unwrap();
|
||||
safe_rename(&src, &dst).unwrap();
|
||||
|
||||
assert!(dst.exists());
|
||||
assert!(!src.exists());
|
||||
let contents = fs::read(&dst).unwrap();
|
||||
assert_eq!(contents, b"hello world");
|
||||
|
||||
fs::remove_file(&dst).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue