Skip to content

Commit f1a56c8

Browse files
committed
progress
1 parent 6197649 commit f1a56c8

1 file changed

Lines changed: 99 additions & 95 deletions

File tree

src/uu/rm/src/rm.rs

Lines changed: 99 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,89 @@ enum RmError {
4747

4848
impl UError for RmError {}
4949

50+
/// Helper function to print verbose message for removed file
51+
fn verbose_removed_file(path: &Path, options: &Options) {
52+
if options.verbose {
53+
println!(
54+
"{}",
55+
translate!("rm-verbose-removed", "file" => normalize(path).quote())
56+
);
57+
}
58+
}
59+
60+
/// Helper function to print verbose message for removed directory
61+
fn verbose_removed_directory(path: &Path, options: &Options) {
62+
if options.verbose {
63+
println!(
64+
"{}",
65+
translate!("rm-verbose-removed-directory", "file" => normalize(path).quote())
66+
);
67+
}
68+
}
69+
70+
/// Helper function to show error with context and return error status
71+
fn show_removal_error(error: std::io::Error, path: &Path) -> bool {
72+
let e = error.map_err_context(|| translate!("rm-error-cannot-remove", "file" => path.quote()));
73+
show_error!("{e}");
74+
true
75+
}
76+
77+
/// Helper function for permission denied errors
78+
fn show_permission_denied_error(path: &Path) -> bool {
79+
show_error!("cannot remove {}: Permission denied", path.quote());
80+
true
81+
}
82+
83+
/// Helper function to show generic removal error
84+
fn show_generic_removal_error(error: std::io::Error, path: &Path) -> bool {
85+
show_error!("cannot remove {}: {error}", path.quote());
86+
true
87+
}
88+
89+
/// Helper function to remove a directory and handle results
90+
fn remove_dir_with_feedback(path: &Path, options: &Options) -> bool {
91+
match fs::remove_dir(path) {
92+
Ok(_) => {
93+
verbose_removed_directory(path, options);
94+
false
95+
}
96+
Err(e) => show_removal_error(e, path),
97+
}
98+
}
99+
100+
/// Helper function to remove directory handling special cases
101+
fn remove_dir_with_special_cases(path: &Path, options: &Options, error_occurred: bool) -> bool {
102+
match fs::remove_dir(path) {
103+
#[cfg(not(target_os = "linux"))]
104+
Err(_) if !error_occurred && !is_readable(path) => {
105+
// For compatibility with GNU test case
106+
// `tests/rm/unread2.sh`, show "Permission denied" in this
107+
// case instead of "Directory not empty".
108+
show_permission_denied_error(path);
109+
true
110+
}
111+
#[cfg(target_os = "linux")]
112+
Err(_) if !error_occurred && path.read_dir().is_err() => {
113+
// For compatibility with GNU test case on Linux
114+
// Check if directory is readable by attempting to read it
115+
show_permission_denied_error(path);
116+
true
117+
}
118+
Err(e) if !error_occurred => show_removal_error(e, path),
119+
Err(_) => {
120+
// If we already had errors while
121+
// trying to remove the children, then there is no need to
122+
// show another error message as we return from each level
123+
// of the recursion.
124+
error_occurred
125+
}
126+
Ok(_) => {
127+
verbose_removed_directory(path, options);
128+
false
129+
}
130+
}
131+
}
132+
50133
#[derive(Eq, PartialEq, Clone, Copy)]
51134
/// Enum, determining when the `rm` will prompt the user about the file deletion
52135
pub enum InteractiveMode {
@@ -472,22 +555,13 @@ fn unsafe_remove_dir_recursive(path: &Path, options: &Options) -> bool {
472555
// If it's empty, this should succeed. If not, we'll get a different error.
473556
match fs::remove_dir(path) {
474557
Ok(_) => {
475-
if options.verbose {
476-
println!(
477-
"{}",
478-
translate!("rm-verbose-removed-directory", "file" => normalize(path).quote())
479-
);
480-
}
558+
verbose_removed_directory(path, options);
481559
return false; // Success
482560
}
483561
Err(_remove_err) => {
484562
// Could not remove the directory. Always show the original permission denied error
485563
// since this indicates a fundamental access issue, even with force flag
486-
let e = e.map_err_context(
487-
|| translate!("rm-error-cannot-remove", "file" => path.quote()),
488-
);
489-
show_error!("{}", e);
490-
error = true;
564+
return show_removal_error(e, path);
491565
}
492566
}
493567
}
@@ -541,19 +615,9 @@ fn unsafe_remove_dir_recursive(path: &Path, options: &Options) -> bool {
541615
}
542616
true
543617
}
544-
Err(e) => {
545-
let e =
546-
e.map_err_context(|| translate!("rm-error-cannot-remove", "file" => path.quote()));
547-
show_error!("{e}");
548-
true
549-
}
618+
Err(e) => show_removal_error(e, path),
550619
Ok(_) => {
551-
if options.verbose {
552-
println!(
553-
"{}",
554-
translate!("rm-verbose-removed-directory", "file" => normalize(path).quote())
555-
);
556-
}
620+
verbose_removed_directory(path, options);
557621
false
558622
}
559623
}
@@ -583,31 +647,7 @@ fn safe_remove_dir_recursive(path: &Path, options: &Options) -> bool {
583647
}
584648

585649
// Use regular fs::remove_dir for the root since we can't unlinkat ourselves
586-
match fs::remove_dir(path) {
587-
Ok(_) => {
588-
if options.verbose {
589-
println!(
590-
"{}",
591-
translate!("rm-verbose-removed-directory", "file" => normalize(path).quote())
592-
);
593-
}
594-
false
595-
}
596-
Err(e) if !error => {
597-
let e = e.map_err_context(
598-
|| translate!("rm-error-cannot-remove", "file" => path.quote()),
599-
);
600-
show_error!("{e}");
601-
true
602-
}
603-
Err(_) => {
604-
// If there has already been at least one error when
605-
// trying to remove the children, then there is no need to
606-
// show another error message as we return from each level
607-
// of the recursion.
608-
error
609-
}
610-
}
650+
remove_dir_with_special_cases(path, options, error)
611651
}
612652
}
613653

@@ -690,11 +730,8 @@ fn safe_remove_dir_recursive_impl(path: &Path, dir_fd: &DirFd, options: &Options
690730
);
691731
show_error!("{e}");
692732
error = true;
693-
} else if options.verbose {
694-
println!(
695-
"{}",
696-
translate!("rm-verbose-removed-directory", "file" => normalize(&entry_path).quote())
697-
);
733+
} else {
734+
verbose_removed_directory(&entry_path, options);
698735
}
699736
}
700737
} else {
@@ -706,11 +743,8 @@ fn safe_remove_dir_recursive_impl(path: &Path, dir_fd: &DirFd, options: &Options
706743
);
707744
show_error!("{e}");
708745
error = true;
709-
} else if options.verbose {
710-
println!(
711-
"{}",
712-
translate!("rm-verbose-removed", "file" => normalize(&entry_path).quote())
713-
);
746+
} else {
747+
verbose_removed_file(&entry_path, options);
714748
}
715749
}
716750
}
@@ -800,7 +834,7 @@ fn remove_dir_recursive(path: &Path, options: &Options) -> bool {
800834
// For compatibility with GNU test case
801835
// `tests/rm/unread2.sh`, show "Permission denied" in this
802836
// case instead of "Directory not empty".
803-
show_error!("cannot remove {}: Permission denied", path.quote());
837+
show_permission_denied_error(path);
804838
error = true;
805839
}
806840
Err(e) if !error => {
@@ -816,11 +850,7 @@ fn remove_dir_recursive(path: &Path, options: &Options) -> bool {
816850
// show another error message as we return from each level
817851
// of the recursion.
818852
}
819-
Ok(_) if options.verbose => println!(
820-
"{}",
821-
translate!("rm-verbose-removed-directory", "file" => normalize(path).quote())
822-
),
823-
Ok(_) => {}
853+
Ok(_) => verbose_removed_directory(path, options),
824854
}
825855

826856
error
@@ -910,23 +940,7 @@ fn remove_dir(path: &Path, options: &Options) -> bool {
910940
}
911941

912942
// Fallback method for non-Linux or when safe traversal is unavailable
913-
match fs::remove_dir(path) {
914-
Ok(_) => {
915-
if options.verbose {
916-
println!(
917-
"{}",
918-
translate!("rm-verbose-removed-directory", "file" => normalize(path).quote())
919-
);
920-
}
921-
false
922-
}
923-
Err(e) => {
924-
let e =
925-
e.map_err_context(|| translate!("rm-error-cannot-remove", "file" => path.quote()));
926-
show_error!("{e}");
927-
true
928-
}
929-
}
943+
remove_dir_with_feedback(path, options)
930944
}
931945

932946
fn remove_file(path: &Path, options: &Options) -> bool {
@@ -940,12 +954,7 @@ fn remove_file(path: &Path, options: &Options) -> bool {
940954
Ok(dir_fd) => {
941955
match dir_fd.unlink_at(file_name, false) {
942956
Ok(_) => {
943-
if options.verbose {
944-
println!(
945-
"{}",
946-
translate!("rm-verbose-removed", "file" => normalize(path).quote())
947-
);
948-
}
957+
verbose_removed_file(path, options);
949958
return false;
950959
}
951960
Err(e) => {
@@ -958,7 +967,7 @@ fn remove_file(path: &Path, options: &Options) -> bool {
958967
)
959968
);
960969
} else {
961-
show_error!("cannot remove {}: {e}", path.quote());
970+
return show_generic_removal_error(e, path);
962971
}
963972
return true;
964973
}
@@ -975,12 +984,7 @@ fn remove_file(path: &Path, options: &Options) -> bool {
975984
// Fallback method for non-Linux or when safe traversal is unavailable
976985
match fs::remove_file(path) {
977986
Ok(_) => {
978-
if options.verbose {
979-
println!(
980-
"{}",
981-
translate!("rm-verbose-removed", "file" => normalize(path).quote())
982-
);
983-
}
987+
verbose_removed_file(path, options);
984988
}
985989
Err(e) => {
986990
if e.kind() == std::io::ErrorKind::PermissionDenied {
@@ -990,7 +994,7 @@ fn remove_file(path: &Path, options: &Options) -> bool {
990994
RmError::CannotRemovePermissionDenied(path.as_os_str().to_os_string())
991995
);
992996
} else {
993-
show_error!("cannot remove {}: {e}", path.quote());
997+
return show_generic_removal_error(e, path);
994998
}
995999
return true;
9961000
}

0 commit comments

Comments
 (0)