mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 11:07:44 +00:00
Merge pull request #3853 from stefins/rm-write-protected
rm: added write-protected check for files
This commit is contained in:
commit
282774a3ef
2 changed files with 63 additions and 2 deletions
|
@ -14,6 +14,8 @@ use clap::{crate_version, Arg, Command};
|
|||
use remove_dir_all::remove_dir_all;
|
||||
use std::collections::VecDeque;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::ErrorKind;
|
||||
use std::io::{stderr, stdin, BufRead, Write};
|
||||
use std::ops::BitOr;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -27,6 +29,7 @@ enum InteractiveMode {
|
|||
Never,
|
||||
Once,
|
||||
Always,
|
||||
PromptProtected,
|
||||
}
|
||||
|
||||
struct Options {
|
||||
|
@ -112,7 +115,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
InteractiveMode::Never
|
||||
InteractiveMode::PromptProtected
|
||||
}
|
||||
},
|
||||
one_fs: matches.contains_id(OPT_ONE_FILE_SYSTEM),
|
||||
|
@ -384,7 +387,7 @@ fn remove_file(path: &Path, options: &Options) -> bool {
|
|||
} else {
|
||||
true
|
||||
};
|
||||
if response {
|
||||
if response && prompt_write_protected(path, false, options) {
|
||||
match fs::remove_file(path) {
|
||||
Ok(_) => {
|
||||
if options.verbose {
|
||||
|
@ -406,6 +409,34 @@ fn remove_file(path: &Path, options: &Options) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
fn prompt_write_protected(path: &Path, is_dir: bool, options: &Options) -> bool {
|
||||
if options.interactive == InteractiveMode::Never {
|
||||
return true;
|
||||
}
|
||||
match File::open(path) {
|
||||
Ok(_) => true,
|
||||
Err(err) => {
|
||||
if err.kind() == ErrorKind::PermissionDenied {
|
||||
if is_dir {
|
||||
prompt(&(format!("rm: remove write-protected directory {}? ", path.quote())))
|
||||
} else {
|
||||
if fs::metadata(path).unwrap().len() == 0 {
|
||||
return prompt(
|
||||
&(format!(
|
||||
"rm: remove write-protected regular empty file {}? ",
|
||||
path.quote()
|
||||
)),
|
||||
);
|
||||
}
|
||||
prompt(&(format!("rm: remove write-protected regular file {}? ", path.quote())))
|
||||
}
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn prompt_file(path: &Path, is_dir: bool) -> bool {
|
||||
if is_dir {
|
||||
prompt(&(format!("rm: remove directory {}? ", path.quote())))
|
||||
|
|
|
@ -363,3 +363,33 @@ fn test_rm_directory_rights_rm1() {
|
|||
assert!(!at.dir_exists("b/c"));
|
||||
assert!(!at.dir_exists("b/d"));
|
||||
}
|
||||
|
||||
#[cfg(feature = "chmod")]
|
||||
#[test]
|
||||
fn test_prompt_write_protected_yes() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let file_1 = "test_rm_prompt_write_protected_1";
|
||||
|
||||
at.touch(file_1);
|
||||
|
||||
scene.ccmd("chmod").arg("0").arg(file_1).succeeds();
|
||||
|
||||
scene.ucmd().arg(file_1).pipe_in("y").succeeds();
|
||||
assert!(!at.file_exists(file_1));
|
||||
}
|
||||
|
||||
#[cfg(feature = "chmod")]
|
||||
#[test]
|
||||
fn test_prompt_write_protected_no() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let file_2 = "test_rm_prompt_write_protected_2";
|
||||
|
||||
at.touch(file_2);
|
||||
|
||||
scene.ccmd("chmod").arg("0").arg(file_2).succeeds();
|
||||
|
||||
scene.ucmd().arg(file_2).pipe_in("n").succeeds();
|
||||
assert!(at.file_exists(file_2));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue