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,
         )
     })?;