mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-10-25 17:22:27 +08:00
fix(windows): use rename fallback for WSL UNC
This commit is contained in:
1 parent
7787b2a01d
commit
cbf140d08c
1 file changed
+2
-53
+2
-53
@@ -423,61 +423,10 @@ pub fn atomic_write(path: &Path, data: &[u8]) -> Result<(), AppError> {
|
||||
|
||||
let replace_error = std::io::Error::last_os_error();
|
||||
// WSL UNC paths reject ReplaceFileW with ERROR_NOT_SUPPORTED (50).
|
||||
// Fall back to rename-based replacement with a rollback backup there.
|
||||
// std::fs::rename uses a different replace-existing API on Windows.
|
||||
let replace_not_supported =
|
||||
replace_error.raw_os_error() == Some(ERROR_NOT_SUPPORTED as i32);
|
||||
if replace_not_supported {
|
||||
let mut backup_name = tmp
|
||||
.file_name()
|
||||
.expect("temporary path must have a file name")
|
||||
.to_os_string();
|
||||
backup_name.push(".backup");
|
||||
let backup = tmp.with_file_name(backup_name);
|
||||
let backup_created = match fs::rename(path, &backup) {
|
||||
Ok(()) => true,
|
||||
Err(source) if source.kind() == std::io::ErrorKind::NotFound => false,
|
||||
Err(source) => {
|
||||
last_error = Some(source);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
match fs::rename(&tmp, path) {
|
||||
Ok(()) => {
|
||||
if backup_created {
|
||||
if let Err(source) = fs::remove_file(&backup) {
|
||||
log::warn!(
|
||||
"Failed to remove atomic-write backup {}: {}",
|
||||
backup.display(),
|
||||
source
|
||||
);
|
||||
}
|
||||
}
|
||||
completed = true;
|
||||
break;
|
||||
}
|
||||
Err(source) => {
|
||||
if backup_created {
|
||||
if let Err(restore_error) = fs::rename(&backup, path) {
|
||||
return Err(AppError::IoContext {
|
||||
context: format!(
|
||||
"原子替换及回滚失败: {} -> {}; 原文件保留在 {}; 回滚错误: {}",
|
||||
tmp.display(),
|
||||
path.display(),
|
||||
backup.display(),
|
||||
restore_error
|
||||
),
|
||||
source,
|
||||
});
|
||||
}
|
||||
}
|
||||
last_error = Some(source);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if replace_error.kind() != std::io::ErrorKind::NotFound {
|
||||
if replace_error.kind() != std::io::ErrorKind::NotFound && !replace_not_supported {
|
||||
last_error = Some(replace_error);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user