Files
macports-base/vendor/patches/tcl/clonefile.patch
T
2026-07-01 16:33:16 +10:00

132 lines
3.5 KiB
Diff

--- vendor/tcl/unix/configure.orig 2026-07-01 15:55:27
+++ vendor/tcl/unix/configure 2026-07-01 16:02:14
@@ -10660,6 +10660,13 @@
if test "x$ac_cv_header_copyfile_h" = xyes
then :
printf '%s\n' "#define HAVE_COPYFILE_H 1" >>confdefs.h
+
+fi
+
+ ac_fn_c_check_header_compile "$LINENO" "sys/clonefile.h" "ac_cv_header_sys_clonefile_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_clonefile_h" = xyes
+then :
+ printf '%s\n' "#define HAVE_SYS_CLONEFILE_H 1" >>confdefs.h
fi
@@ -10670,6 +10677,13 @@
fi
+ ac_fn_c_check_func "$LINENO" "clonefile" "ac_cv_func_clonefile"
+if test "x$ac_cv_func_clonefile" = xyes
+then :
+ printf '%s\n' "#define HAVE_CLONEFILE 1" >>confdefs.h
+
+fi
+
if test $tcl_corefoundation = yes; then
ac_fn_c_check_header_compile "$LINENO" "libkern/OSAtomic.h" "ac_cv_header_libkern_OSAtomic_h" "$ac_includes_default"
if test "x$ac_cv_header_libkern_OSAtomic_h" = xyes
--- vendor/tcl/unix/tclUnixFCmd.c.orig 2025-11-12 03:22:57
+++ vendor/tcl/unix/tclUnixFCmd.c 2026-04-10 10:14:21
@@ -48,7 +48,23 @@
#endif /* !HAVE_STRUCT_STAT_ST_BLKSIZE */
#ifdef HAVE_FTS
#include <fts.h>
+#endif
+#ifdef HAVE_SYS_CLONEFILE_H
+#include <sys/clonefile.h>
+#ifndef CLONE_NOOWNERCOPY
+#include <unistd.h>
+#endif
+#endif /* HAVE_SYS_CLONEFILE_H */
+#ifdef HAVE_CLONEFILE
+#if defined(__APPLE__) && \
+ defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
+ MAC_OS_X_VERSION_MIN_REQUIRED < 101200
+#define MayUseCloneFile() (clonefile != NULL)
+#else
+#define MayUseCloneFile() (1)
#endif
+#endif /* HAVE_CLONEFILE */
+
/*
* The following constants specify the type of callback when
@@ -489,14 +505,58 @@ DoCopyFile(
}
return TCL_OK;
}
-
+
/*
*----------------------------------------------------------------------
*
+ * TclUnixCloneFile -
+ *
+ * Helper function for TclUnixCopyFile. Clones one regular file, using
+ * clonefile().
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * A file is cloned.
+ *
+ *----------------------------------------------------------------------
+ */
+#ifdef HAVE_CLONEFILE
+int
+TclUnixCloneFile(
+ const char *src, /* Pathname of file to clone (native). */
+ const char *dst, /* Pathname of file to create (native). */
+ const Tcl_StatBuf *statBufPtr,
+ /* Used to copy attributes. */
+ int dontCopyAtts) /* If flag set, don't copy attributes. */
+{
+#ifndef CLONE_NOOWNERCOPY
+#define CLONE_NOOWNERCOPY 0
+ if (dontCopyAtts && geteuid() == 0) {
+ /* ownership would always be copied without this flag */
+ return TCL_ERROR;
+ }
+#endif
+ if (clonefile(src, dst, CLONE_NOFOLLOW|CLONE_NOOWNERCOPY) == 0) {
+ if (dontCopyAtts || CopyFileAtts(src, dst, statBufPtr) == TCL_OK) {
+ return TCL_OK;
+ }
+ }
+ unlink(dst); /* INTL: Native. */
+ return TCL_ERROR;
+}
+#endif
+
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclUnixCopyFile -
*
* Helper function for TclpCopyFile. Copies one regular file, using
- * read() and write().
+ * read() and write(), or clones it with TclUnixCloneFile() if
+ * supported.
*
* Results:
* A standard Tcl result.
@@ -520,6 +580,13 @@ TclUnixCopyFile(
size_t blockSize; /* Optimal I/O blocksize for filesystem */
char *buffer; /* Data buffer for copy */
ssize_t nread;
+
+#ifdef HAVE_CLONEFILE
+ if (MayUseCloneFile() &&
+ TclUnixCloneFile(src, dst, statBufPtr, dontCopyAtts) == TCL_OK) {
+ return TCL_OK;
+ }
+#endif
#ifdef DJGPP
#define BINMODE |O_BINARY