Skip to content

Commit 1619870

Browse files
committed
refactor(linux/rm): avoid redundant DirFd opening in safe_remove_dir_recursive
Move DirFd opening out of safe_remove_dir_recursive_impl to safe_remove_dir_recursive to open the directory file descriptor once per level instead of twice, improving efficiency and reducing potential for errors in recursive directory removal on Linux.
1 parent 971a8bd commit 1619870

File tree

1 file changed

+8
-22
lines changed

1 file changed

+8
-22
lines changed

src/uu/rm/src/platform/linux.rs

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,10 @@ pub fn safe_remove_dir_recursive(
258258
}
259259
};
260260

261-
// Try to open the directory using DirFd for secure traversal
262-
if let Err(e) = DirFd::open(path) {
263-
// If we can't open the directory for safe traversal,
264-
// handle the error appropriately and try to remove if possible
265-
if e.kind() == std::io::ErrorKind::PermissionDenied {
261+
// Open directory fd once for this level; traversal impl will close it
262+
let dir_fd = match DirFd::open(path) {
263+
Ok(fd) => fd,
264+
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => {
266265
// Try to remove the directory directly if it's empty
267266
if fs::remove_dir(path).is_ok() {
268267
verbose_removed_directory(path, options);
@@ -272,10 +271,10 @@ pub fn safe_remove_dir_recursive(
272271
// show permission denied error for GNU compatibility
273272
return show_permission_denied_error(path);
274273
}
275-
return show_removal_error(e, path);
276-
}
274+
Err(e) => return show_removal_error(e, path),
275+
};
277276

278-
let error = safe_remove_dir_recursive_impl(path, options, progress_bar);
277+
let error = safe_remove_dir_recursive_impl(path, dir_fd, options, progress_bar);
279278

280279
// After processing all children, remove the directory itself
281280
if error {
@@ -313,23 +312,10 @@ pub fn safe_remove_dir_recursive(
313312

314313
pub fn safe_remove_dir_recursive_impl(
315314
path: &Path,
315+
mut dir_fd: DirFd,
316316
options: &Options,
317317
progress_bar: Option<&ProgressBar>,
318318
) -> bool {
319-
// Read directory entries using safe traversal
320-
let dir_fd = match DirFd::open(path) {
321-
Ok(fd) => fd,
322-
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => {
323-
if !options.force {
324-
show_permission_denied_error(path);
325-
}
326-
return !options.force;
327-
}
328-
Err(e) => {
329-
return handle_error_with_force(e, path, options);
330-
}
331-
};
332-
333319
let entries = match dir_fd.read_dir() {
334320
Ok(entries) => entries,
335321
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => {

0 commit comments

Comments
 (0)