Skip to content

Commit 2fb45c1

Browse files
rm: fix error reporting for -r on Linux fixing #9011 (#10111)
* rm: fix error reporting for -r on Linux * rm: add stricter assertion for error tracking test --------- Co-authored-by: Alex Lyon <dev@arct.rs>
1 parent 8d02762 commit 2fb45c1

File tree

2 files changed

+10
-9
lines changed

2 files changed

+10
-9
lines changed

src/uu/rm/src/platform/unix.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ pub fn safe_remove_dir_recursive_impl(path: &Path, dir_fd: &DirFd, options: &Opt
371371
let entry_stat = match dir_fd.stat_at(&entry_name, false) {
372372
Ok(stat) => stat,
373373
Err(e) => {
374-
error = handle_error_with_force(e, &entry_path, options);
374+
error |= handle_error_with_force(e, &entry_path, options);
375375
continue;
376376
}
377377
};
@@ -395,21 +395,21 @@ pub fn safe_remove_dir_recursive_impl(path: &Path, dir_fd: &DirFd, options: &Opt
395395
// If we can't open the subdirectory for safe traversal,
396396
// try to handle it as best we can with safe operations
397397
if e.kind() == std::io::ErrorKind::PermissionDenied {
398-
error = handle_permission_denied(
398+
error |= handle_permission_denied(
399399
dir_fd,
400400
entry_name.as_ref(),
401401
&entry_path,
402402
options,
403403
);
404404
} else {
405-
error = handle_error_with_force(e, &entry_path, options);
405+
error |= handle_error_with_force(e, &entry_path, options);
406406
}
407407
continue;
408408
}
409409
};
410410

411411
let child_error = safe_remove_dir_recursive_impl(&entry_path, &child_dir_fd, options);
412-
error = error || child_error;
412+
error |= child_error;
413413

414414
// Ask user permission if needed for this subdirectory
415415
if !child_error
@@ -421,12 +421,12 @@ pub fn safe_remove_dir_recursive_impl(path: &Path, dir_fd: &DirFd, options: &Opt
421421

422422
// Remove the now-empty subdirectory using safe unlinkat
423423
if !child_error {
424-
error = handle_unlink(dir_fd, entry_name.as_ref(), &entry_path, true, options);
424+
error |= handle_unlink(dir_fd, entry_name.as_ref(), &entry_path, true, options);
425425
}
426426
} else {
427427
// Remove file - check if user wants to remove it first
428428
if prompt_file_with_stat(&entry_path, &entry_stat, options) {
429-
error = handle_unlink(dir_fd, entry_name.as_ref(), &entry_path, false, options);
429+
error |= handle_unlink(dir_fd, entry_name.as_ref(), &entry_path, false, options);
430430
}
431431
}
432432
}

tests/by-util/test_rm.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,9 +1140,10 @@ fn test_rm_directory_not_writable() {
11401140

11411141
// Check for expected error message
11421142
// When the parent directory (b/a) doesn't have write permission,
1143-
// we get "Permission denied" when trying to remove the subdirectory
1144-
let stderr = result.stderr_str();
1145-
assert!(stderr.contains("rm: cannot remove 'b/a/p': Permission denied"));
1143+
// we get "Permission denied" when trying to remove the subdirectory.
1144+
// The error tracking must be correct so we don't attempt to remove the parent
1145+
// directory after child failure (which would produce extra "Directory not empty" errors).
1146+
result.stderr_only("rm: cannot remove 'b/a/p': Permission denied\n");
11461147

11471148
// Check which directories still exist
11481149
assert!(at.dir_exists("b/a/p")); // Should still exist (parent not writable)

0 commit comments

Comments
 (0)