mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 19:47:45 +00:00
rm: correct prompt for removing inaccessible dir
Change the prompt when attempting to remove an inaccessible directory. Before this commit, the prompt was rm: remove write-protected directory 'dir'? After this commit, the prompt is rm: attempt removal of inaccessible directory 'dir'? This required slightly adjusting the logic for which prompt messages to display under which circumstances. Fixes #7309.
This commit is contained in:
parent
bc995283c4
commit
2b531b78ef
2 changed files with 44 additions and 20 deletions
|
@ -339,15 +339,18 @@ fn is_dir_empty(path: &Path) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn is_readable_metadata(metadata: &Metadata) -> bool {
|
||||||
|
let mode = metadata.permissions().mode();
|
||||||
|
(mode & 0o400) > 0
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether the given file or directory is readable.
|
/// Whether the given file or directory is readable.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn is_readable(path: &Path) -> bool {
|
fn is_readable(path: &Path) -> bool {
|
||||||
match std::fs::metadata(path) {
|
match std::fs::metadata(path) {
|
||||||
Err(_) => false,
|
Err(_) => false,
|
||||||
Ok(metadata) => {
|
Ok(metadata) => is_readable_metadata(&metadata),
|
||||||
let mode = metadata.permissions().mode();
|
|
||||||
(mode & 0o400) > 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,15 +360,18 @@ fn is_readable(_path: &Path) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn is_writable_metadata(metadata: &Metadata) -> bool {
|
||||||
|
let mode = metadata.permissions().mode();
|
||||||
|
(mode & 0o200) > 0
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether the given file or directory is writable.
|
/// Whether the given file or directory is writable.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn is_writable(path: &Path) -> bool {
|
fn is_writable(path: &Path) -> bool {
|
||||||
match std::fs::metadata(path) {
|
match std::fs::metadata(path) {
|
||||||
Err(_) => false,
|
Err(_) => false,
|
||||||
Ok(metadata) => {
|
Ok(metadata) => is_writable_metadata(&metadata),
|
||||||
let mode = metadata.permissions().mode();
|
|
||||||
(mode & 0o200) > 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,20 +629,25 @@ fn prompt_file_permission_readonly(path: &Path) -> bool {
|
||||||
// Most cases are covered by keep eye out for edge cases
|
// Most cases are covered by keep eye out for edge cases
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata) -> bool {
|
fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata) -> bool {
|
||||||
use std::os::unix::fs::PermissionsExt;
|
match (
|
||||||
let mode = metadata.permissions().mode();
|
is_readable_metadata(metadata),
|
||||||
// Check if directory has user write permissions
|
is_writable_metadata(metadata),
|
||||||
// Why is S_IWUSR showing up as a u16 on macos?
|
options.interactive,
|
||||||
#[allow(clippy::unnecessary_cast)]
|
) {
|
||||||
let user_writable = (mode & (libc::S_IWUSR as u32)) != 0;
|
(false, false, _) => prompt_yes!(
|
||||||
if !user_writable {
|
"attempt removal of inaccessible directory {}?",
|
||||||
prompt_yes!("remove write-protected directory {}?", path.quote())
|
path.quote()
|
||||||
} else if options.interactive == InteractiveMode::Always {
|
),
|
||||||
prompt_yes!("remove directory {}?", path.quote())
|
(false, true, InteractiveMode::Always) => prompt_yes!(
|
||||||
} else {
|
"attempt removal of inaccessible directory {}?",
|
||||||
true
|
path.quote()
|
||||||
|
),
|
||||||
|
(true, false, _) => prompt_yes!("remove write-protected directory {}?", path.quote()),
|
||||||
|
(_, _, InteractiveMode::Always) => prompt_yes!("remove directory {}?", path.quote()),
|
||||||
|
(_, _, _) => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the path is referring to current or parent directory , if it is referring to current or any parent directory in the file tree e.g '/../..' , '../..'
|
/// Checks if the path is referring to current or parent directory , if it is referring to current or any parent directory in the file tree e.g '/../..' , '../..'
|
||||||
fn path_is_current_or_parent_directory(path: &Path) -> bool {
|
fn path_is_current_or_parent_directory(path: &Path) -> bool {
|
||||||
let path_str = os_str_as_bytes(path.as_os_str());
|
let path_str = os_str_as_bytes(path.as_os_str());
|
||||||
|
|
|
@ -874,6 +874,19 @@ fn test_inaccessible_dir_nonempty() {
|
||||||
assert!(at.dir_exists("dir"));
|
assert!(at.dir_exists("dir"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
#[test]
|
||||||
|
fn test_inaccessible_dir_interactive() {
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
at.mkdir("dir");
|
||||||
|
at.set_mode("dir", 0);
|
||||||
|
ucmd.args(&["-i", "-d", "dir"])
|
||||||
|
.pipe_in("y\n")
|
||||||
|
.succeeds()
|
||||||
|
.stderr_only("rm: attempt removal of inaccessible directory 'dir'? ");
|
||||||
|
assert!(!at.dir_exists("dir"));
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inaccessible_dir_recursive() {
|
fn test_inaccessible_dir_recursive() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue