diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 466a8d6c1..e858e3b0a 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -305,16 +305,28 @@ fn remove_dir(path: &Path, options: &Options) -> bool { true }; if response { - match fs::remove_dir(path) { - Ok(_) => { - if options.verbose { - println!("removed '{}'", path.display()); + if let Ok(mut read_dir) = fs::read_dir(path) { + if options.dir && read_dir.next().is_none() { + match fs::remove_dir(path) { + Ok(_) => { + if options.verbose { + println!("removed directory '{}'", path.display()); + } + } + Err(e) => { + show_error!("cannot remove '{}': {}", path.display(), e); + return true; + } } - } - Err(e) => { - show_error!("removing '{}': {}", path.display(), e); + } else { + // directory can be read but is not empty + show_error!("cannot remove '{}': Directory not empty", path.display()); return true; } + } else { + // GNU's rm shows this message if directory is empty but not readable + show_error!("cannot remove '{}': Directory not empty", path.display()); + return true; } } diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index 27568957a..06d1d435d 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -115,6 +115,23 @@ fn test_rm_empty_directory() { assert!(!at.dir_exists(dir)); } +#[test] +fn test_rm_non_empty_directory() { + let (at, mut ucmd) = at_and_ucmd!(); + let dir = "test_rm_non_empty_dir"; + let file_a = &format!("{}/test_rm_non_empty_file_a", dir); + + at.mkdir(dir); + at.touch(file_a); + + let result = ucmd.arg("-d").arg(dir).fails(); + assert!(result + .stderr + .contains(&format!("cannot remove '{}': Directory not empty", dir))); + assert!(at.file_exists(file_a)); + assert!(at.dir_exists(dir)); +} + #[test] fn test_rm_recursive() { let (at, mut ucmd) = at_and_ucmd!();