From 3fe58393bc3cfe38cbdf803549d66de1b74fccb0 Mon Sep 17 00:00:00 2001 From: Mads Marquart <mads@marquart.dk> Date: Fri, 5 Apr 2024 04:21:00 +0200 Subject: [PATCH] macOS: Use `libc` definitions for copyfile `COPYFILE_ALL` is not yet exposed in `libc`, but the rest of what we need is, so use those definitions instead of manually defining them. --- library/std/src/sys/pal/unix/fs.rs | 47 ++++++------------------------ 1 file changed, 9 insertions(+), 38 deletions(-) diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 99b6da60c14..35d9778cb9b 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -1817,39 +1817,9 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { use crate::sync::atomic::{AtomicBool, Ordering}; - const COPYFILE_ACL: u32 = 1 << 0; - const COPYFILE_STAT: u32 = 1 << 1; - const COPYFILE_XATTR: u32 = 1 << 2; - const COPYFILE_DATA: u32 = 1 << 3; + const COPYFILE_ALL: libc::copyfile_flags_t = libc::COPYFILE_METADATA | libc::COPYFILE_DATA; - const COPYFILE_SECURITY: u32 = COPYFILE_STAT | COPYFILE_ACL; - const COPYFILE_METADATA: u32 = COPYFILE_SECURITY | COPYFILE_XATTR; - const COPYFILE_ALL: u32 = COPYFILE_METADATA | COPYFILE_DATA; - - const COPYFILE_STATE_COPIED: u32 = 8; - - #[allow(non_camel_case_types)] - type copyfile_state_t = *mut libc::c_void; - #[allow(non_camel_case_types)] - type copyfile_flags_t = u32; - - extern "C" { - fn fcopyfile( - from: libc::c_int, - to: libc::c_int, - state: copyfile_state_t, - flags: copyfile_flags_t, - ) -> libc::c_int; - fn copyfile_state_alloc() -> copyfile_state_t; - fn copyfile_state_free(state: copyfile_state_t) -> libc::c_int; - fn copyfile_state_get( - state: copyfile_state_t, - flag: u32, - dst: *mut libc::c_void, - ) -> libc::c_int; - } - - struct FreeOnDrop(copyfile_state_t); + struct FreeOnDrop(libc::copyfile_state_t); impl Drop for FreeOnDrop { fn drop(&mut self) { // The code below ensures that `FreeOnDrop` is never a null pointer @@ -1857,7 +1827,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { // `copyfile_state_free` returns -1 if the `to` or `from` files // cannot be closed. However, this is not considered this an // error. - copyfile_state_free(self.0); + libc::copyfile_state_free(self.0); } } } @@ -1866,6 +1836,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { // We store the availability in a global to avoid unnecessary syscalls static HAS_FCLONEFILEAT: AtomicBool = AtomicBool::new(true); syscall! { + // Mirrors `libc::fclonefileat` fn fclonefileat( srcfd: libc::c_int, dst_dirfd: libc::c_int, @@ -1902,22 +1873,22 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> { // We ensure that `FreeOnDrop` never contains a null pointer so it is // always safe to call `copyfile_state_free` let state = unsafe { - let state = copyfile_state_alloc(); + let state = libc::copyfile_state_alloc(); if state.is_null() { return Err(crate::io::Error::last_os_error()); } FreeOnDrop(state) }; - let flags = if writer_metadata.is_file() { COPYFILE_ALL } else { COPYFILE_DATA }; + let flags = if writer_metadata.is_file() { COPYFILE_ALL } else { libc::COPYFILE_DATA }; - cvt(unsafe { fcopyfile(reader.as_raw_fd(), writer.as_raw_fd(), state.0, flags) })?; + cvt(unsafe { libc::fcopyfile(reader.as_raw_fd(), writer.as_raw_fd(), state.0, flags) })?; let mut bytes_copied: libc::off_t = 0; cvt(unsafe { - copyfile_state_get( + libc::copyfile_state_get( state.0, - COPYFILE_STATE_COPIED, + libc::COPYFILE_STATE_COPIED as u32, core::ptr::addr_of_mut!(bytes_copied) as *mut libc::c_void, ) })?;