@@ -1475,11 +1475,7 @@ mod remove_dir_impl {
1475
1475
}
1476
1476
1477
1477
// Modern implementation using openat(), unlinkat() and fdopendir()
1478
- #[ cfg( not( any(
1479
- all( target_os = "macos" , target_arch = "x86_64" ) ,
1480
- target_os = "redox" ,
1481
- target_os = "espidf"
1482
- ) ) ) ]
1478
+ #[ cfg( not( any( target_os = "redox" , target_os = "espidf" ) ) ) ]
1483
1479
mod remove_dir_impl {
1484
1480
use super :: { cstr, lstat, Dir , DirEntry , InnerReadDir , ReadDir } ;
1485
1481
use crate :: ffi:: CStr ;
@@ -1489,8 +1485,39 @@ mod remove_dir_impl {
1489
1485
use crate :: path:: { Path , PathBuf } ;
1490
1486
use crate :: sync:: Arc ;
1491
1487
use crate :: sys:: { cvt, cvt_r} ;
1488
+
1489
+ #[ cfg( not( all( target_os = "macos" , target_arch = "x86_64" ) , ) ) ]
1492
1490
use libc:: { fdopendir, openat, unlinkat} ;
1493
1491
1492
+ #[ cfg( all( target_os = "macos" , target_arch = "x86_64" ) ) ]
1493
+ mod macos_weak {
1494
+ use crate :: sys:: weak:: weak;
1495
+ use libc:: { c_char, c_int, DIR } ;
1496
+
1497
+ pub unsafe fn openat ( dirfd : c_int , pathname : * const c_char , flags : c_int ) -> c_int {
1498
+ weak ! ( fn openat( c_int, * const c_char, c_int) -> c_int) ;
1499
+ openat. get ( ) . unwrap ( ) ( dirfd, pathname, flags)
1500
+ }
1501
+
1502
+ pub unsafe fn fdopendir ( fd : c_int ) -> * mut DIR {
1503
+ weak ! ( fn fdopendir( c_int) -> * mut DIR , "fdopendir$INODE64" ) ;
1504
+ fdopendir. get ( ) . unwrap ( ) ( fd)
1505
+ }
1506
+
1507
+ pub unsafe fn unlinkat ( dirfd : c_int , pathname : * const c_char , flags : c_int ) -> c_int {
1508
+ weak ! ( fn unlinkat( c_int, * const c_char, c_int) -> c_int) ;
1509
+ unlinkat. get ( ) . unwrap ( ) ( dirfd, pathname, flags)
1510
+ }
1511
+
1512
+ pub fn has_openat ( ) -> bool {
1513
+ weak ! ( fn openat( c_int, * const c_char, c_int) -> c_int) ;
1514
+ openat. get ( ) . is_some ( )
1515
+ }
1516
+ }
1517
+
1518
+ #[ cfg( all( target_os = "macos" , target_arch = "x86_64" ) ) ]
1519
+ use macos_weak:: { fdopendir, openat, unlinkat} ;
1520
+
1494
1521
pub fn openat_nofollow_dironly ( parent_fd : Option < RawFd > , p : & CStr ) -> io:: Result < OwnedFd > {
1495
1522
let fd = cvt_r ( || unsafe {
1496
1523
openat (
@@ -1629,7 +1656,7 @@ mod remove_dir_impl {
1629
1656
}
1630
1657
}
1631
1658
1632
- pub fn remove_dir_all ( p : & Path ) -> io:: Result < ( ) > {
1659
+ fn remove_dir_all_modern ( p : & Path ) -> io:: Result < ( ) > {
1633
1660
// We cannot just call remove_dir_all_loop() here because that would not delete a passed
1634
1661
// symlink. No need to worry about races, because remove_dir_all_loop() does not descend
1635
1662
// into symlinks.
@@ -1640,4 +1667,20 @@ mod remove_dir_impl {
1640
1667
remove_dir_all_loop ( p)
1641
1668
}
1642
1669
}
1670
+
1671
+ #[ cfg( not( all( target_os = "macos" , target_arch = "x86_64" ) ) ) ]
1672
+ pub fn remove_dir_all ( p : & Path ) -> io:: Result < ( ) > {
1673
+ remove_dir_all_modern ( p)
1674
+ }
1675
+
1676
+ #[ cfg( all( target_os = "macos" , target_arch = "x86_64" ) ) ]
1677
+ pub fn remove_dir_all ( p : & Path ) -> io:: Result < ( ) > {
1678
+ if macos_weak:: has_openat ( ) {
1679
+ // openat() is available with macOS 10.10+, just like unlinkat() and fdopendir()
1680
+ remove_dir_all_modern ( p)
1681
+ } else {
1682
+ // fall back to classic implementation
1683
+ crate :: sys_common:: fs:: remove_dir_all ( p)
1684
+ }
1685
+ }
1643
1686
}
0 commit comments