Skip to content

Commit 78b51cb

Browse files
committed
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`.
1 parent 58c336d commit 78b51cb

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

src/uu/rm/src/rm.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use std::fs::{self, Metadata};
1212
use std::ops::BitOr;
1313
#[cfg(not(windows))]
1414
use std::os::unix::ffi::OsStrExt;
15+
#[cfg(unix)]
16+
use std::os::unix::fs::PermissionsExt;
1517
use std::path::MAIN_SEPARATOR;
1618
use std::path::{Path, PathBuf};
1719
use uucore::display::Quotable;
@@ -328,6 +330,25 @@ pub fn remove(files: &[&OsStr], options: &Options) -> bool {
328330
had_err
329331
}
330332

333+
/// Whether the given file or directory is writable.
334+
#[cfg(unix)]
335+
fn is_writable(path: &Path) -> bool {
336+
match std::fs::metadata(path) {
337+
Err(_) => false,
338+
Ok(metadata) => {
339+
let mode = metadata.permissions().mode();
340+
(mode & 0o200) > 0
341+
}
342+
}
343+
}
344+
345+
/// Whether the given file or directory is writable.
346+
#[cfg(not(unix))]
347+
fn is_writable(_path: &Path) -> bool {
348+
// TODO Not yet implemented.
349+
true
350+
}
351+
331352
#[allow(clippy::cognitive_complexity)]
332353
fn handle_dir(path: &Path, options: &Options) -> bool {
333354
let mut had_err = false;
@@ -515,7 +536,7 @@ fn prompt_file(path: &Path, options: &Options) -> bool {
515536
return true;
516537
};
517538

518-
if options.interactive == InteractiveMode::Always && !metadata.permissions().readonly() {
539+
if options.interactive == InteractiveMode::Always && is_writable(path) {
519540
return if metadata.len() == 0 {
520541
prompt_yes!("remove regular empty file {}?", path.quote())
521542
} else {
@@ -527,7 +548,7 @@ fn prompt_file(path: &Path, options: &Options) -> bool {
527548

528549
fn prompt_file_permission_readonly(path: &Path) -> bool {
529550
match fs::metadata(path) {
530-
Ok(metadata) if !metadata.permissions().readonly() => true,
551+
Ok(_) if is_writable(path) => true,
531552
Ok(metadata) if metadata.len() == 0 => prompt_yes!(
532553
"remove write-protected regular empty file {}?",
533554
path.quote()

0 commit comments

Comments
 (0)