@@ -444,22 +444,24 @@ pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath, Fd1: std::os::fd::As
444
444
}
445
445
}
446
446
447
- #[ cfg( all ( target_os = "linux" , target_env = "gnu" ) ) ]
447
+ #[ cfg( target_os = "linux" ) ]
448
448
#[ cfg( feature = "fs" ) ]
449
- libc_bitflags ! {
449
+ bitflags :: bitflags ! {
450
450
/// Flags for use with [`renameat2`].
451
451
#[ cfg_attr( docsrs, doc( cfg( feature = "fs" ) ) ) ]
452
+ #[ derive( Copy , Clone , Debug , Eq , Hash , Ord , PartialEq , PartialOrd ) ]
453
+ #[ repr( transparent) ]
452
454
pub struct RenameFlags : u32 {
453
455
/// Atomically exchange `old_path` and `new_path`.
454
- RENAME_EXCHANGE ;
456
+ const RENAME_EXCHANGE = 1 << 1 ;
455
457
/// Don't overwrite `new_path` of the rename. Return an error if `new_path` already
456
458
/// exists.
457
- RENAME_NOREPLACE ;
459
+ const RENAME_NOREPLACE = 1 << 0 ;
458
460
/// creates a "whiteout" object at the source of the rename at the same time as performing
459
461
/// the rename.
460
462
///
461
463
/// This operation makes sense only for overlay/union filesystem implementations.
462
- RENAME_WHITEOUT ;
464
+ const RENAME_WHITEOUT = 1 << 2 ;
463
465
}
464
466
}
465
467
@@ -471,7 +473,7 @@ feature! {
471
473
///
472
474
/// # See Also
473
475
/// * [`rename`](https://man7.org/linux/man-pages/man2/rename.2.html)
474
- #[ cfg( all ( target_os = "linux" , target_env = "gnu" ) ) ]
476
+ #[ cfg( target_os = "linux" ) ]
475
477
pub fn renameat2<P1 : ?Sized + NixPath , P2 : ?Sized + NixPath , Fd1 : std:: os:: fd:: AsFd , Fd2 : std:: os:: fd:: AsFd >(
476
478
old_dirfd: Fd1 ,
477
479
old_path: & P1 ,
@@ -483,7 +485,25 @@ pub fn renameat2<P1: ?Sized + NixPath, P2: ?Sized + NixPath, Fd1: std::os::fd::A
483
485
484
486
let res = old_path. with_nix_path( |old_cstr| {
485
487
new_path. with_nix_path( |new_cstr| unsafe {
486
- libc:: renameat2(
488
+ // Use raw syscall instead of libc::renameat2 to support musl libc and other
489
+ // environments where the libc function may not be available.
490
+ //
491
+ // Syscall numbers from the Linux kernel source:
492
+ // https://github.com/torvalds/linux/blob/master/arch/x86/entry/syscalls/syscall_64.tbl
493
+ // https://github.com/torvalds/linux/blob/master/arch/arm64/include/asm/unistd32.h
494
+ #[ cfg( target_arch = "x86_64" ) ]
495
+ const SYS_RENAMEAT2 : libc:: c_long = 316 ;
496
+ #[ cfg( target_arch = "x86" ) ]
497
+ const SYS_RENAMEAT2 : libc:: c_long = 353 ;
498
+ #[ cfg( target_arch = "aarch64" ) ]
499
+ const SYS_RENAMEAT2 : libc:: c_long = 276 ;
500
+ #[ cfg( target_arch = "arm" ) ]
501
+ const SYS_RENAMEAT2 : libc:: c_long = 382 ;
502
+ #[ cfg( target_arch = "riscv64" ) ]
503
+ const SYS_RENAMEAT2 : libc:: c_long = 276 ;
504
+
505
+ libc:: syscall(
506
+ SYS_RENAMEAT2 ,
487
507
old_dirfd. as_fd( ) . as_raw_fd( ) ,
488
508
old_cstr. as_ptr( ) ,
489
509
new_dirfd. as_fd( ) . as_raw_fd( ) ,
@@ -492,7 +512,7 @@ pub fn renameat2<P1: ?Sized + NixPath, P2: ?Sized + NixPath, Fd1: std::os::fd::A
492
512
)
493
513
} )
494
514
} ) ??;
495
- Errno :: result( res) . map( drop)
515
+ Errno :: result( res as c_int ) . map( drop)
496
516
}
497
517
498
518
fn wrap_readlink_result( mut v: Vec <u8 >, len: ssize_t) -> Result <OsString > {
0 commit comments