From 416c2b7f899cb2cc20004ca5d68dd194a2b6c694 Mon Sep 17 00:00:00 2001 From: Shinichiro Hamaji Date: Sun, 9 Apr 2017 01:03:16 +0900 Subject: [PATCH] rm: Remove invalid symlinks Checking with file.exists() was not good for this purpose as Path::exists() returns false for invalid symlinks. --- src/rm/rm.rs | 24 +++++++++++------------- tests/test_rm.rs | 10 ++++++++++ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/rm/rm.rs b/src/rm/rm.rs index 73c2d07ed..3c099a4dd 100644 --- a/src/rm/rm.rs +++ b/src/rm/rm.rs @@ -128,16 +128,8 @@ fn remove(files: Vec, force: bool, interactive: InteractiveMode, one_fs: for filename in &files { let filename = &filename[..]; let file = Path::new(filename); - if file.exists() { - let is_dir = match file.symlink_metadata() { - Ok(metadata) => metadata.is_dir(), - Err(e) => { - had_err = true; - show_error!("could not read metadata of '{}': {}", filename, e); - continue; - } - }; - if is_dir { + match file.symlink_metadata() { + Ok(metadata) => if metadata.is_dir() { if recursive && (filename != "/" || !preserve_root) { if interactive != InteractiveMode::InteractiveAlways { if let Err(e) = fs::remove_dir_all(file) { @@ -214,10 +206,16 @@ fn remove(files: Vec, force: bool, interactive: InteractiveMode, one_fs: } } else { had_err = remove_file(&file, interactive, verbose).bitor(had_err); + }, + Err(e) => { + // TODO: When the error is not about missing files + // (e.g., permission), even rm -f should fail with + // outputting the error, but there's no easy eay. + if !force { + had_err = true; + show_error!("no such file or directory '{}'", filename); + } } - } else if !force { - show_error!("no such file or directory '{}'", filename); - had_err = true; } } diff --git a/tests/test_rm.rs b/tests/test_rm.rs index b0083e019..9f7f46b56 100644 --- a/tests/test_rm.rs +++ b/tests/test_rm.rs @@ -148,3 +148,13 @@ fn test_rm_dir_symlink() { ucmd.arg(link).succeeds(); } + +#[test] +fn test_rm_invalid_symlink() { + let (at, mut ucmd) = at_and_ucmd!(); + let link = "test_rm_invalid_symlink"; + + at.symlink(link, link); + + ucmd.arg(link).succeeds(); +}