Skip to content

Commit ab44c39

Browse files
committed
uucore: use symlink_metadata for backup lookup
Avoids Path::exists() returning false for a live symlink whose target stat fails (observed under wasmtime), and also keeps a dangling .~N~ symlink from being overwritten by a --backup=numbered rename.
1 parent 49bff40 commit ab44c39

1 file changed

Lines changed: 7 additions & 2 deletions

File tree

src/uucore/src/lib/features/backup_control.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ use std::{
9191
error::Error,
9292
ffi::{OsStr, OsString},
9393
fmt::{Debug, Display},
94+
fs,
9495
path::{Path, PathBuf},
9596
};
9697

@@ -442,7 +443,11 @@ fn numbered_backup_path(path: &Path) -> PathBuf {
442443
let mut i: u64 = 1;
443444
loop {
444445
let new_path = simple_backup_path(path, OsString::from(format!(".~{i}~")));
445-
if !new_path.exists() {
446+
// Use `symlink_metadata` rather than `exists()` so that a dangling
447+
// symlink still counts as an existing backup (avoiding a silent
448+
// overwrite), and so we do not report a live symlink as missing when
449+
// the target cannot be stat'd.
450+
if fs::symlink_metadata(&new_path).is_err() {
446451
return new_path;
447452
}
448453
i += 1;
@@ -451,7 +456,7 @@ fn numbered_backup_path(path: &Path) -> PathBuf {
451456

452457
fn existing_backup_path<S: AsRef<OsStr>>(path: &Path, suffix: S) -> PathBuf {
453458
let test_path = simple_backup_path(path, OsString::from(".~1~"));
454-
if test_path.exists() {
459+
if fs::symlink_metadata(&test_path).is_ok() {
455460
return numbered_backup_path(path);
456461
}
457462
simple_backup_path(path, suffix.as_ref())

0 commit comments

Comments
 (0)