<pre style='margin:0'>
Christopher Nielsen (mascguy) pushed a commit to branch master
in repository macports-legacy-support.
</pre>
<p><a href="https://github.com/macports/macports-legacy-support/commit/22cc53b4e8312d8b5f5b2b0b2b570f072a0f9e26">https://github.com/macports/macports-legacy-support/commit/22cc53b4e8312d8b5f5b2b0b2b570f072a0f9e26</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 22cc53b4e8312d8b5f5b2b0b2b570f072a0f9e26
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Wed Jan 15 10:12:48 2025 -0800
<span style='display:block; white-space:pre;color:#404040;'> Add fix for fstatx_np() on 10.4 Rosetta.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> This provides the missing byte swap for fstatx_np() on 10.4 Rosetta.
</span><span style='display:block; white-space:pre;color:#404040;'> See the comment for details.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> TESTED:
</span><span style='display:block; white-space:pre;color:#404040;'> Passes tests on all platforms, including 10.4 Rosetta cases.
</span>---
include/MacportsLegacySupport.h | 11 ++++
src/copyfile.3 | 2 +-
src/statxx.c | 115 +++++++++++++++++++++++++++++++++++++++-
3 files changed, 126 insertions(+), 2 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/include/MacportsLegacySupport.h b/include/MacportsLegacySupport.h
</span><span style='display:block; white-space:pre;color:#808080;'>index 4539c28..155ea3a 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/include/MacportsLegacySupport.h
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/include/MacportsLegacySupport.h
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -51,6 +51,13 @@
</span> #define __MPLS_64BIT 0
#endif
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/* True for Apple-only ppc build */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#if defined(__ppc__) && __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define __MPLS_APPLE_PPC__ 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define __MPLS_APPLE_PPC__ 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /*
* More concise and more comprehensive target OS definition, to simplify
* many conditionals.
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -321,6 +328,10 @@
</span> #define __MPLS_SDK_SUPPORT_STAT64__ (__MPLS_SDK_MAJOR < 1050)
#define __MPLS_LIB_SUPPORT_STAT64__ (__MPLS_TARGET_OSVER < 1050)
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/* fstatx_np() malfunctions on 10.4 Rosetta */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define __MPLS_LIB_FIX_TIGER_ROSETTA__ (__MPLS_TARGET_OSVER < 1050 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ && __MPLS_APPLE_PPC__)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /* Compound macros, bundling functionality needed by multiple single features. */
#define __MPLS_LIB_NEED_BEST_FCHDIR__ (__MPLS_LIB_SUPPORT_ATCALLS__ \
|| __MPLS_LIB_SUPPORT_SETATTRLISTAT__)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/copyfile.3 b/src/copyfile.3
</span><span style='display:block; white-space:pre;color:#808080;'>index b0edce8..40e1ace 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/copyfile.3
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/copyfile.3
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -75,7 +75,7 @@ The
</span> parameter controls which contents are copied:
.Bl -tag -width COPYFILE_XATTR
.It Dv COPYFILE_ACL
<span style='display:block; white-space:pre;background:#ffe0e0;'>-Copy the source file's access control lists (doesn't work on 10.4 Rosetta).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Copy the source file's access control lists.
</span> .It Dv COPYFILE_STAT
Copy the source file's POSIX information (mode, modification time, etc.).
.It Dv COPYFILE_XATTR
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/statxx.c b/src/statxx.c
</span><span style='display:block; white-space:pre;color:#808080;'>index edd624d..0fd92ff 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/statxx.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/statxx.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,5 +1,5 @@
</span> /*
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Copyright (c) 2024 Frederick H. G. Wright II <fw@fwright.net>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 2025 Frederick H. G. Wright II <fw@fwright.net>
</span> *
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -40,6 +40,119 @@ struct stat64 __DARWIN_STRUCT_STAT64;
</span>
#endif /*__MPLS_LIB_SUPPORT_STAT64__ || __MPLS_LIB_SUPPORT_ATCALLS__*/
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#if __MPLS_LIB_FIX_TIGER_ROSETTA__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The fstatx_np() function screws up when run under 10.4 Rosetta, due to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * a missing byte swap of the fd. This only happens with a non-NULL fsec
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * argument. The fix is trivial, but determining when to apply it is not,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * and is important, since applying the fix when it isn't needed would have
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * the effect of introducing the bug, rather than fixing it.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The conditions where the bug is present are:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 1) Having a non-NULL fsec parameter.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 2) Running under Rosetta.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 3) This being the 10.4 Rosetta.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 4) The Rosetta bug's not having been fixed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Conditions 1 and 2 are easily established (#2 via an undocumented sysctl).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Condition 3 is tricky. We can't just rely on the build-target OS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * version, since it's legal to run code built for one OS version on a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * later one. Although we don't yet handle that issue in general, the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * consequences of ignoring it would be bad, as noted, so we need to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * actually check.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * To make matters worse, not only is there no straightforward
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * way to obtain the Rosetta version, but even the libSystem version isn't
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * made available straightforwardly. And condition 4 is a complete
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * wildcard, though it's highly unlikely that someone would have applied
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * a patch for such an esoteric bug on such an old system.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The method we use here is:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 1) The check for the non-NULL fsec arg is trivial.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 2) We use a sysctl() to determine whether we're running under Rosetta.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 3) We use the presence of copyfile_init() to determine whether it's
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * a 10.4 libSystem. That function was part of the preliminary (unadvertised)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * copyfile implementation in 10.4, and was removed in 10.5. It's highly
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * unlikely that someone would have patched a later libSystem to add this
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * obsolete function, so this is probably accurate. In fact, we do provide
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * this function in 10.5 as a compatibility aid, but that won't match
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * dlsym(RTLD_NEXT,...), so it has no effect.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 4) We assume that the libSsystem version is a valid proxy for the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Rosetta version. That should be the case in any normal install, but
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * if someone played mix-'n-match with system components, it might not be.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * 5) We assume that the Rosetta bug has not been fixed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * In principle, there's a more elaborate way to make the deteremination,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * based on testing the actual behavior of the function, but for simplicity
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * we avoid that at the present, and use the conditions above. If any of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * the above assumptions were to become incorrect, we'd need to implement
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * the more elaborate scheme. Of course, this entire section of code
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * is only present when building for 10.4 ppc.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Note that we only need to provide the basic variant, since the wrappers
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * providing the additional variants will call this version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Also note that chmod_np() is also broken in 10.4 Rosetta, but the nature of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * the bug is unknwon, and hence there's no fix provided. It's known *not*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * to be a simple byte-swapping issue.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <dlfcn.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/sysctl.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/types.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <libkern/OSByteOrder.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* sysctl to check whether we're running natively (non-ppc only) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define SYSCTL_NATIVE "sysctl.proc_native"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Function present in 10.4 and not later */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define TIGER_TEST_FUNC "copyfile_init"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Test whether it's 10.4 Rosetta */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* -1 no, 1 yes */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+is_tiger_rosetta(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int native;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ size_t native_sz = sizeof(native);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (sysctlbyname(SYSCTL_NATIVE, &native, &native_sz, NULL, 0) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* If sysctl failed, must be real ppc. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (native) return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Definitely Rosetta - see if it's 10.4. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return dlsym(RTLD_NEXT, TIGER_TEST_FUNC) ? 1 : -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Wrapper with optional byte swap of fd */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fstatx_np(int fildes, struct stat *buf, filesec_t fsec)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static __typeof__(fstatx_np) *fstatx = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static int tiger_rosetta = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!fstatx) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!(fstatx = dlsym(RTLD_NEXT, "fstatx_np"))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Something's badly wrong if we can't find the function */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ abort();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* If known not 10.4 Rosetta or NULL fsec, just call the function normally */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (tiger_rosetta < 0 || fsec == NULL) return (*fstatx)(fildes, buf, fsec);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* If we don't yet know the Rosetta status, get it */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!tiger_rosetta) tiger_rosetta = is_tiger_rosetta();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Iff it's 10.4 Rosetta, byte-swap the fd */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return (*fstatx)(tiger_rosetta >= 0 ? OSSwapInt32(fildes) : fildes,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ buf, fsec);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif /* __MPLS_LIB_FIX_TIGER_ROSETTA__ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> #if __MPLS_LIB_SUPPORT_STAT64__
/*
</pre><pre style='margin:0'>
</pre>