@@ -1474,124 +1474,6 @@ mod remove_dir_impl {
1474
1474
pub use crate :: sys_common:: fs:: remove_dir_all;
1475
1475
}
1476
1476
1477
- // Dynamically choose implementation Macos x86-64: modern for 10.10+, fallback for older versions
1478
- #[ cfg( all( target_os = "macos" , target_arch = "x86_64" ) ) ]
1479
- mod remove_dir_impl {
1480
- use super :: { cstr, lstat, Dir , InnerReadDir , ReadDir } ;
1481
- use crate :: ffi:: CStr ;
1482
- use crate :: io;
1483
- use crate :: os:: unix:: io:: { AsRawFd , FromRawFd , IntoRawFd } ;
1484
- use crate :: os:: unix:: prelude:: { OwnedFd , RawFd } ;
1485
- use crate :: path:: { Path , PathBuf } ;
1486
- use crate :: sync:: Arc ;
1487
- use crate :: sys:: weak:: weak;
1488
- use crate :: sys:: { cvt, cvt_r} ;
1489
- use libc:: { c_char, c_int, DIR } ;
1490
-
1491
- pub fn openat_nofollow_dironly ( parent_fd : Option < RawFd > , p : & CStr ) -> io:: Result < OwnedFd > {
1492
- weak ! ( fn openat( c_int, * const c_char, c_int) -> c_int) ;
1493
- let fd = cvt_r ( || unsafe {
1494
- openat. get ( ) . unwrap ( ) (
1495
- parent_fd. unwrap_or ( libc:: AT_FDCWD ) ,
1496
- p. as_ptr ( ) ,
1497
- libc:: O_CLOEXEC | libc:: O_RDONLY | libc:: O_NOFOLLOW | libc:: O_DIRECTORY ,
1498
- )
1499
- } ) ?;
1500
- Ok ( unsafe { OwnedFd :: from_raw_fd ( fd) } )
1501
- }
1502
-
1503
- fn fdreaddir ( dir_fd : OwnedFd ) -> io:: Result < ( ReadDir , RawFd ) > {
1504
- weak ! ( fn fdopendir( c_int) -> * mut DIR , "fdopendir$INODE64" ) ;
1505
- let ptr = unsafe { fdopendir. get ( ) . unwrap ( ) ( dir_fd. as_raw_fd ( ) ) } ;
1506
- if ptr. is_null ( ) {
1507
- return Err ( io:: Error :: last_os_error ( ) ) ;
1508
- }
1509
- let dirp = Dir ( ptr) ;
1510
- // file descriptor is automatically closed by libc::closedir() now, so give up ownership
1511
- let new_parent_fd = dir_fd. into_raw_fd ( ) ;
1512
- // a valid root is not needed because we do not call any functions involving the full path
1513
- // of the DirEntrys.
1514
- let dummy_root = PathBuf :: new ( ) ;
1515
- Ok ( (
1516
- ReadDir {
1517
- inner : Arc :: new ( InnerReadDir { dirp, root : dummy_root } ) ,
1518
- end_of_stream : false ,
1519
- } ,
1520
- new_parent_fd,
1521
- ) )
1522
- }
1523
-
1524
- fn remove_dir_all_recursive ( parent_fd : Option < RawFd > , p : & Path ) -> io:: Result < ( ) > {
1525
- weak ! ( fn unlinkat( c_int, * const c_char, c_int) -> c_int) ;
1526
-
1527
- let pcstr = cstr ( p) ?;
1528
-
1529
- // entry is expected to be a directory, open as such
1530
- let fd = openat_nofollow_dironly ( parent_fd, & pcstr) ?;
1531
-
1532
- // open the directory passing ownership of the fd
1533
- let ( dir, fd) = fdreaddir ( fd) ?;
1534
- for child in dir {
1535
- let child = child?;
1536
- match child. entry . d_type {
1537
- libc:: DT_DIR => {
1538
- remove_dir_all_recursive ( Some ( fd) , Path :: new ( & child. file_name ( ) ) ) ?;
1539
- }
1540
- libc:: DT_UNKNOWN => {
1541
- match cvt ( unsafe { unlinkat. get ( ) . unwrap ( ) ( fd, child. name_cstr ( ) . as_ptr ( ) , 0 ) } )
1542
- {
1543
- // type unknown - try to unlink
1544
- Err ( err) if err. raw_os_error ( ) == Some ( libc:: EPERM ) => {
1545
- // if the file is a directory unlink fails with EPERM
1546
- remove_dir_all_recursive ( Some ( fd) , Path :: new ( & child. file_name ( ) ) ) ?;
1547
- }
1548
- result => {
1549
- result?;
1550
- }
1551
- }
1552
- }
1553
- _ => {
1554
- // not a directory -> unlink
1555
- cvt ( unsafe { unlinkat. get ( ) . unwrap ( ) ( fd, child. name_cstr ( ) . as_ptr ( ) , 0 ) } ) ?;
1556
- }
1557
- }
1558
- }
1559
-
1560
- // unlink the directory after removing its contents
1561
- cvt ( unsafe {
1562
- unlinkat. get ( ) . unwrap ( ) (
1563
- parent_fd. unwrap_or ( libc:: AT_FDCWD ) ,
1564
- pcstr. as_ptr ( ) ,
1565
- libc:: AT_REMOVEDIR ,
1566
- )
1567
- } ) ?;
1568
- Ok ( ( ) )
1569
- }
1570
-
1571
- fn remove_dir_all_modern ( p : & Path ) -> io:: Result < ( ) > {
1572
- // We cannot just call remove_dir_all_recursive() here because that would not delete a passed
1573
- // symlink. No need to worry about races, because remove_dir_all_recursive() does not recurse
1574
- // into symlinks.
1575
- let attr = lstat ( p) ?;
1576
- if attr. file_type ( ) . is_symlink ( ) {
1577
- crate :: fs:: remove_file ( p)
1578
- } else {
1579
- remove_dir_all_recursive ( None , p)
1580
- }
1581
- }
1582
-
1583
- pub fn remove_dir_all ( p : & Path ) -> io:: Result < ( ) > {
1584
- weak ! ( fn openat( c_int, * const c_char, c_int) -> c_int) ;
1585
- if openat. get ( ) . is_some ( ) {
1586
- // openat() is available with macOS 10.10+, just like unlinkat() and fdopendir()
1587
- remove_dir_all_modern ( p)
1588
- } else {
1589
- // fall back to classic implementation
1590
- crate :: sys_common:: fs:: remove_dir_all ( p)
1591
- }
1592
- }
1593
- }
1594
-
1595
1477
// Modern implementation using openat(), unlinkat() and fdopendir()
1596
1478
#[ cfg( not( any(
1597
1479
all( target_os = "macos" , target_arch = "x86_64" ) ,
0 commit comments