1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 11:07:44 +00:00

rm: check write permissions instead of readonly()

Check the user write permission directly from the mode instead of using
the `Permissions::readonly()` method. This seems to more closely match
the behavior of GNU `rm`.
This commit is contained in:
Jeffrey Finkelstein 2025-02-15 22:43:43 -05:00
parent 58c336d5c3
commit 78b51cb939

View file

@ -12,6 +12,8 @@ use std::fs::{self, Metadata};
use std::ops::BitOr; use std::ops::BitOr;
#[cfg(not(windows))] #[cfg(not(windows))]
use std::os::unix::ffi::OsStrExt; use std::os::unix::ffi::OsStrExt;
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
use std::path::MAIN_SEPARATOR; use std::path::MAIN_SEPARATOR;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use uucore::display::Quotable; use uucore::display::Quotable;
@ -328,6 +330,25 @@ pub fn remove(files: &[&OsStr], options: &Options) -> bool {
had_err had_err
} }
/// Whether the given file or directory is writable.
#[cfg(unix)]
fn is_writable(path: &Path) -> bool {
match std::fs::metadata(path) {
Err(_) => false,
Ok(metadata) => {
let mode = metadata.permissions().mode();
(mode & 0o200) > 0
}
}
}
/// Whether the given file or directory is writable.
#[cfg(not(unix))]
fn is_writable(_path: &Path) -> bool {
// TODO Not yet implemented.
true
}
#[allow(clippy::cognitive_complexity)] #[allow(clippy::cognitive_complexity)]
fn handle_dir(path: &Path, options: &Options) -> bool { fn handle_dir(path: &Path, options: &Options) -> bool {
let mut had_err = false; let mut had_err = false;
@ -515,7 +536,7 @@ fn prompt_file(path: &Path, options: &Options) -> bool {
return true; return true;
}; };
if options.interactive == InteractiveMode::Always && !metadata.permissions().readonly() { if options.interactive == InteractiveMode::Always && is_writable(path) {
return if metadata.len() == 0 { return if metadata.len() == 0 {
prompt_yes!("remove regular empty file {}?", path.quote()) prompt_yes!("remove regular empty file {}?", path.quote())
} else { } else {
@ -527,7 +548,7 @@ fn prompt_file(path: &Path, options: &Options) -> bool {
fn prompt_file_permission_readonly(path: &Path) -> bool { fn prompt_file_permission_readonly(path: &Path) -> bool {
match fs::metadata(path) { match fs::metadata(path) {
Ok(metadata) if !metadata.permissions().readonly() => true, Ok(_) if is_writable(path) => true,
Ok(metadata) if metadata.len() == 0 => prompt_yes!( Ok(metadata) if metadata.len() == 0 => prompt_yes!(
"remove write-protected regular empty file {}?", "remove write-protected regular empty file {}?",
path.quote() path.quote()