darwin: bring back macos-specific copyfile(3) (#3654)

Co-authored-by: Mingye Wang <arthur200126@gmail.com>
This commit is contained in:
Niklas Mischkulnig 2023-03-13 11:54:31 +01:00 committed by GitHub
parent 91a7e49846
commit d4eb276eea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -65,6 +65,7 @@
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__)
# include <copyfile.h>
# include <sys/sysctl.h> # include <sys/sysctl.h>
#elif defined(__linux__) && !defined(FICLONE) #elif defined(__linux__) && !defined(FICLONE)
# include <sys/ioctl.h> # include <sys/ioctl.h>
@ -1240,6 +1241,32 @@ done:
} }
static ssize_t uv__fs_copyfile(uv_fs_t* req) { static ssize_t uv__fs_copyfile(uv_fs_t* req) {
#if defined(__APPLE__) && !TARGET_OS_IPHONE
/* On macOS, use the native copyfile(3). */
copyfile_flags_t flags;
/* Don't overwrite the destination if its permissions disallow it. */
if (faccessat(AT_FDCWD, req->new_path, R_OK | W_OK, AT_EACCESS)) {
if (errno != ENOENT)
return UV__ERR(errno);
}
flags = COPYFILE_ALL;
if (req->flags & UV_FS_COPYFILE_FICLONE)
flags |= COPYFILE_CLONE;
if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE)
flags |= COPYFILE_CLONE_FORCE;
if (req->flags & UV_FS_COPYFILE_EXCL)
flags |= COPYFILE_EXCL;
if (copyfile(req->path, req->new_path, NULL, flags))
return UV__ERR(errno);
return 0;
#else /* defined(__APPLE__) && !TARGET_OS_IPHONE */
uv_fs_t fs_req; uv_fs_t fs_req;
uv_file srcfd; uv_file srcfd;
uv_file dstfd; uv_file dstfd;
@ -1415,6 +1442,7 @@ out:
errno = UV__ERR(result); errno = UV__ERR(result);
return -1; return -1;
#endif /* defined(__APPLE__) && !TARGET_OS_IPHONE */
} }
static void uv__to_stat(struct stat* src, uv_stat_t* dst) { static void uv__to_stat(struct stat* src, uv_stat_t* dst) {