<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>