PR-3753279.diff   [plain text]


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 */
 
@@ -2875,6 +2879,9 @@
     curbuf->b_marks_read = TRUE;
 }
 #endif
+#ifdef HAVE_COPYFILE
+    copyfile_state_t	copyfile_state = NULL;
+#endif
 
 #if defined(FEAT_CRYPT) || defined(PROTO)
 /*
@@ -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)
     {