Skip to content

Commit a67b629

Browse files
authored
Rollup merge of #94724 - cuviper:rmdirall-cstr, r=Dylan-DPC
unix: Avoid name conversions in `remove_dir_all_recursive` Each recursive call was creating an `OsString` for a `&Path`, only for it to be turned into a `CString` right away. Instead we can directly pass `.name_cstr()`, saving two allocations each time.
2 parents ff54e34 + ef3e33b commit a67b629

File tree

1 file changed

+9
-10
lines changed
  • library/std/src/sys/unix

1 file changed

+9
-10
lines changed

library/std/src/sys/unix/fs.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -1604,17 +1604,15 @@ mod remove_dir_impl {
16041604
}
16051605
}
16061606

1607-
fn remove_dir_all_recursive(parent_fd: Option<RawFd>, p: &Path) -> io::Result<()> {
1608-
let pcstr = cstr(p)?;
1609-
1607+
fn remove_dir_all_recursive(parent_fd: Option<RawFd>, path: &CStr) -> io::Result<()> {
16101608
// try opening as directory
1611-
let fd = match openat_nofollow_dironly(parent_fd, &pcstr) {
1609+
let fd = match openat_nofollow_dironly(parent_fd, &path) {
16121610
Err(err) if err.raw_os_error() == Some(libc::ENOTDIR) => {
16131611
// not a directory - don't traverse further
16141612
return match parent_fd {
16151613
// unlink...
16161614
Some(parent_fd) => {
1617-
cvt(unsafe { unlinkat(parent_fd, pcstr.as_ptr(), 0) }).map(drop)
1615+
cvt(unsafe { unlinkat(parent_fd, path.as_ptr(), 0) }).map(drop)
16181616
}
16191617
// ...unless this was supposed to be the deletion root directory
16201618
None => Err(err),
@@ -1627,26 +1625,27 @@ mod remove_dir_impl {
16271625
let (dir, fd) = fdreaddir(fd)?;
16281626
for child in dir {
16291627
let child = child?;
1628+
let child_name = child.name_cstr();
16301629
match is_dir(&child) {
16311630
Some(true) => {
1632-
remove_dir_all_recursive(Some(fd), Path::new(&child.file_name()))?;
1631+
remove_dir_all_recursive(Some(fd), child_name)?;
16331632
}
16341633
Some(false) => {
1635-
cvt(unsafe { unlinkat(fd, child.name_cstr().as_ptr(), 0) })?;
1634+
cvt(unsafe { unlinkat(fd, child_name.as_ptr(), 0) })?;
16361635
}
16371636
None => {
16381637
// POSIX specifies that calling unlink()/unlinkat(..., 0) on a directory can succeed
16391638
// if the process has the appropriate privileges. This however can causing orphaned
16401639
// directories requiring an fsck e.g. on Solaris and Illumos. So we try recursing
16411640
// into it first instead of trying to unlink() it.
1642-
remove_dir_all_recursive(Some(fd), Path::new(&child.file_name()))?;
1641+
remove_dir_all_recursive(Some(fd), child_name)?;
16431642
}
16441643
}
16451644
}
16461645

16471646
// unlink the directory after removing its contents
16481647
cvt(unsafe {
1649-
unlinkat(parent_fd.unwrap_or(libc::AT_FDCWD), pcstr.as_ptr(), libc::AT_REMOVEDIR)
1648+
unlinkat(parent_fd.unwrap_or(libc::AT_FDCWD), path.as_ptr(), libc::AT_REMOVEDIR)
16501649
})?;
16511650
Ok(())
16521651
}
@@ -1659,7 +1658,7 @@ mod remove_dir_impl {
16591658
if attr.file_type().is_symlink() {
16601659
crate::fs::remove_file(p)
16611660
} else {
1662-
remove_dir_all_recursive(None, p)
1661+
remove_dir_all_recursive(None, &cstr(p)?)
16631662
}
16641663
}
16651664

0 commit comments

Comments
 (0)