Integrate macos x86-64 remove_dir_all() impl. Step 2: readd
This commit is contained in:
parent
41b4423cdf
commit
735f60c34f
1 changed files with 60 additions and 6 deletions
|
@ -1483,11 +1483,7 @@ mod remove_dir_impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modern implementation using openat(), unlinkat() and fdopendir()
|
// Modern implementation using openat(), unlinkat() and fdopendir()
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(target_os = "redox", target_os = "espidf")))]
|
||||||
all(target_os = "macos", target_arch = "x86_64"),
|
|
||||||
target_os = "redox",
|
|
||||||
target_os = "espidf"
|
|
||||||
)))]
|
|
||||||
mod remove_dir_impl {
|
mod remove_dir_impl {
|
||||||
use super::{cstr, lstat, Dir, DirEntry, InnerReadDir, ReadDir};
|
use super::{cstr, lstat, Dir, DirEntry, InnerReadDir, ReadDir};
|
||||||
use crate::ffi::CStr;
|
use crate::ffi::CStr;
|
||||||
|
@ -1497,7 +1493,49 @@ mod remove_dir_impl {
|
||||||
use crate::path::{Path, PathBuf};
|
use crate::path::{Path, PathBuf};
|
||||||
use crate::sync::Arc;
|
use crate::sync::Arc;
|
||||||
use crate::sys::{cvt, cvt_r};
|
use crate::sys::{cvt, cvt_r};
|
||||||
|
|
||||||
|
#[cfg(not(all(target_os = "macos", target_arch = "x86_64"),))]
|
||||||
use libc::{fdopendir, openat, unlinkat};
|
use libc::{fdopendir, openat, unlinkat};
|
||||||
|
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
|
||||||
|
use macos_weak::{fdopendir, openat, unlinkat};
|
||||||
|
|
||||||
|
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
|
||||||
|
mod macos_weak {
|
||||||
|
use crate::sys::weak::weak;
|
||||||
|
use libc::{c_char, c_int, DIR};
|
||||||
|
|
||||||
|
fn get_openat_fn() -> Option<unsafe extern "C" fn(c_int, *const c_char, c_int) -> c_int> {
|
||||||
|
weak!(fn openat(c_int, *const c_char, c_int) -> c_int);
|
||||||
|
openat.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_openat() -> bool {
|
||||||
|
get_openat_fn().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn openat(dirfd: c_int, pathname: *const c_char, flags: c_int) -> c_int {
|
||||||
|
get_openat_fn().map(|openat| openat(dirfd, pathname, flags)).unwrap_or_else(|| {
|
||||||
|
crate::sys::unix::os::set_errno(libc::ENOSYS);
|
||||||
|
-1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn fdopendir(fd: c_int) -> *mut DIR {
|
||||||
|
weak!(fn fdopendir(c_int) -> *mut DIR, "fdopendir$INODE64");
|
||||||
|
fdopendir.get().map(|fdopendir| fdopendir(fd)).unwrap_or_else(|| {
|
||||||
|
crate::sys::unix::os::set_errno(libc::ENOSYS);
|
||||||
|
crate::ptr::null_mut()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn unlinkat(dirfd: c_int, pathname: *const c_char, flags: c_int) -> c_int {
|
||||||
|
weak!(fn unlinkat(c_int, *const c_char, c_int) -> c_int);
|
||||||
|
unlinkat.get().map(|unlinkat| unlinkat(dirfd, pathname, flags)).unwrap_or_else(|| {
|
||||||
|
crate::sys::unix::os::set_errno(libc::ENOSYS);
|
||||||
|
-1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn openat_nofollow_dironly(parent_fd: Option<RawFd>, p: &CStr) -> io::Result<OwnedFd> {
|
pub fn openat_nofollow_dironly(parent_fd: Option<RawFd>, p: &CStr) -> io::Result<OwnedFd> {
|
||||||
let fd = cvt_r(|| unsafe {
|
let fd = cvt_r(|| unsafe {
|
||||||
|
@ -1609,7 +1647,7 @@ mod remove_dir_impl {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_dir_all(p: &Path) -> io::Result<()> {
|
fn remove_dir_all_modern(p: &Path) -> io::Result<()> {
|
||||||
// We cannot just call remove_dir_all_recursive() here because that would not delete a passed
|
// We cannot just call remove_dir_all_recursive() here because that would not delete a passed
|
||||||
// symlink. No need to worry about races, because remove_dir_all_recursive() does not recurse
|
// symlink. No need to worry about races, because remove_dir_all_recursive() does not recurse
|
||||||
// into symlinks.
|
// into symlinks.
|
||||||
|
@ -1620,4 +1658,20 @@ mod remove_dir_impl {
|
||||||
remove_dir_all_recursive(None, p)
|
remove_dir_all_recursive(None, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(all(target_os = "macos", target_arch = "x86_64")))]
|
||||||
|
pub fn remove_dir_all(p: &Path) -> io::Result<()> {
|
||||||
|
remove_dir_all_modern(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
|
||||||
|
pub fn remove_dir_all(p: &Path) -> io::Result<()> {
|
||||||
|
if macos_weak::has_openat() {
|
||||||
|
// openat() is available with macOS 10.10+, just like unlinkat() and fdopendir()
|
||||||
|
remove_dir_all_modern(p)
|
||||||
|
} else {
|
||||||
|
// fall back to classic implementation
|
||||||
|
crate::sys_common::fs::remove_dir_all(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue