Index: src/auto/config.h
===================================================================
--- src/auto/config.h (revision 57762)
+++ src/auto/config.h (working copy)
@@ -432,3 +432,9 @@
/* Define if fcntl()'s F_SETFD command knows about FD_CLOEXEC */
#define HAVE_FD_CLOEXEC 1
+
+/* Define if there is a copyfile() */
+#define HAVE_COPYFILE 1
+
+/* Define if there is a copyfile.h */
+#define HAVE_COPYFILE_H 1
Index: src/fileio.c
===================================================================
--- src/fileio.c (revision 57776)
+++ src/fileio.c (working copy)
@@ -29,6 +29,10 @@
# include <utime.h> /* for struct utimbuf */
#endif
+#if defined(HAVE_COPYFILE_H)
+#include <copyfile.h>
+#endif
+
#define BUFSIZE 8192 /* size of normal write buffer */
#define SMBUFSIZE 256 /* size of emergency write buffer */
@@ -3220,6 +3217,9 @@
int write_undo_file = FALSE;
context_sha256_T sha_ctx;
#endif
+#ifdef HAVE_COPYFILE
+ copyfile_state_t copyfile_state = NULL;
+#endif
if (fname == NULL || *fname == NUL) /* safety check */
return FAIL;
@@ -3659,6 +3666,13 @@
if (!newfile)
acl = mch_get_acl(fname);
#endif
+#ifdef HAVE_COPYFILE
+ if (!newfile && copyfile((char*)fname, NULL, 0, COPYFILE_XATTR | COPYFILE_CHECK))
+ {
+ copyfile_state = copyfile_state_alloc();
+ copyfile((char*)fname, NULL, copyfile_state, 0);
+ }
+#endif
/*
* If 'backupskip' is not empty, don't make a backup for some files.
@@ -4037,6 +4051,10 @@
#ifdef HAVE_ACL
mch_set_acl(backup, acl);
#endif
+#ifdef HAVE_COPYFILE
+ if (copyfile_state)
+ copyfile(NULL, (char*)backup, copyfile_state, COPYFILE_XATTR);
+#endif
#ifdef HAVE_SELINUX
mch_copy_sec(fname, backup);
#endif
@@ -4717,6 +4735,10 @@
/* Set the inode when creating a new file. */
buf_setino(buf);
#endif
+#ifdef HAVE_COPYFILE
+ if (!backup_copy && copyfile_state)
+ copyfile(NULL, (char*)wfname, copyfile_state, COPYFILE_XATTR);
+#endif
if (close(fd) != 0)
{
@@ -5036,6 +5058,10 @@
#ifdef HAVE_ACL
mch_free_acl(acl);
#endif
+#ifdef HAVE_COPYFILE
+ if (copyfile_state)
+ copyfile_state_free(copyfile_state);
+#endif
if (errmsg != NULL)
{