Skip to content

Commit

Permalink
cp: clone on macOS
Browse files Browse the repository at this point in the history
* configure.ac: Check for fclonefileat.
* src/copy.c [HAVE_FCLONEFILEAT && !USE_XATTR]:
Include <sys/clonefile.h>.
(copy_reg): If possible, use fclonefileat to clone.
  • Loading branch information
eggert committed Nov 22, 2021
1 parent 41bec08 commit 5e36c0c
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 0 deletions.
5 changes: 5 additions & 0 deletions NEWS
Expand Up @@ -30,6 +30,11 @@ GNU coreutils NEWS -*- outline -*-

** Improvements

On macOS, cp creates a copy-on-write clone if source and destination
are regular files on the same APFS file system, the destination does
not already exist, and cp is preserving mode and timestamps (e.g.,
'cp -p', 'cp -a').

sort --debug now diagnoses issues with --field-separator characters
that conflict with characters possibly used in numbers.

Expand Down
3 changes: 3 additions & 0 deletions configure.ac
Expand Up @@ -320,6 +320,9 @@ if test $utils_cv_localtime_cache = yes; then
AC_DEFINE([LOCALTIME_CACHE], [1], [FIXME])
fi

# macOS >= 10.12
AC_CHECK_FUNCS([fclonefileat])

# Assume that if getattrat exists, it's compatible with Solaris 11.
AC_CHECK_FUNCS([getattrat])
if test $ac_cv_func_getattrat = yes; then
Expand Down
12 changes: 12 additions & 0 deletions src/copy.c
Expand Up @@ -90,6 +90,10 @@
# define FICLONE _IOW (0x94, 9, int)
#endif

#if HAVE_FCLONEFILEAT && !USE_XATTR
# include <sys/clonefile.h>
#endif

#ifndef HAVE_FCHOWN
# define HAVE_FCHOWN false
# define fchown(fd, uid, gid) (-1)
Expand Down Expand Up @@ -1245,6 +1249,14 @@ copy_reg (char const *src_name, char const *dst_name,

if (*new_dst)
{
#if HAVE_FCLONEFILEAT && !USE_XATTR
int clone_flags = x->preserve_ownership ? 0 : CLONE_NOOWNERCOPY;
if (data_copy_required && x->reflink_mode
&& x->preserve_mode && x->preserve_timestamps
&& fclonefileat (source_desc, AT_FDCWD, dst_name, clone_flags) == 0)
goto close_src_desc;
#endif

/* To allow copying xattrs on read-only files, create with u+w.
This satisfies an inode permission check done by
xattr_permission in fs/xattr.c of the GNU/Linux kernel. */
Expand Down

0 comments on commit 5e36c0c

Please sign in to comment.