<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/03c7f1c1dd924cb2e0b9a9a694988810e7fb249f">https://github.com/macports/macports-legacy-support/commit/03c7f1c1dd924cb2e0b9a9a694988810e7fb249f</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 03c7f1c1dd924cb2e0b9a9a694988810e7fb249f
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Fri Jun 27 20:14:44 2025 -0700

<span style='display:block; white-space:pre;color:#404040;'>    statxx: Add fix for 10.4 ppc64 *stat*() bug.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Since the 10.4 ppc64 *stat*() functions typically return garbage in
</span><span style='display:block; white-space:pre;color:#404040;'>    the tv_nsec values of the timestamps, rather than the correct zero, we
</span><span style='display:block; white-space:pre;color:#404040;'>    provide wrappers to clear them.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Also applies the new GET_OS_FUNC macro to the existing fstatx_np()
</span><span style='display:block; white-space:pre;color:#404040;'>    wrapper.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Also fixes a couple of typos in a comment.
</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 ppc64.
</span>---
 src/statxx.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 120 insertions(+), 19 deletions(-)

<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 7a67a5d..5af1397 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;'>@@ -17,9 +17,10 @@
</span> /* MP support header */
 #include "MacportsLegacySupport.h"
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#if __MPLS_LIB_SUPPORT_STAT64__ || __MPLS_LIB_SUPPORT_ATCALLS__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#if __MPLS_LIB_SUPPORT_STAT64__ || __MPLS_LIB_SUPPORT_ATCALLS__ \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   || __MPLS_LIB_FIX_TIGER_PPC64__
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-/* Common setup for both kinds of *stat*() calls provided here */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Common setup for all versions of *stat*() calls provided here */
</span> 
 /*
  * Cause our own refs to always use the 32-bit-inode variants.  This
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -27,18 +28,127 @@
</span>  * our implementations are needed.  It means that the referenced function
  * names are always the "unadorned" versions, except when we explicitly
  * add a suffix.
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * This also makes the dlsym() interface common code.
</span>  */
 
 #define _DARWIN_NO_64_BIT_INODE 1
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <dlfcn.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stddef.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> #include <sys/stat.h>
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-/* Make sure we have "struct sta64" */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include "compiler.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Make sure we have "struct stat64" */
</span> #if !__MPLS_HAVE_STAT64
 struct stat64 __DARWIN_STRUCT_STAT64;
 #endif /* !__MPLS_HAVE_STAT64 */
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#endif /*__MPLS_LIB_SUPPORT_STAT64__ || __MPLS_LIB_SUPPORT_ATCALLS__*/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define GET_OS_FUNC(name) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  static __typeof__(name) *os_##name = NULL; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (MPLS_SLOWPATH(!os_##name)) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (!(os_##name = dlsym(RTLD_NEXT, #name))) 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;'>+#endif /* __MPLS_LIB_SUPPORT_... */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#if __MPLS_LIB_FIX_TIGER_PPC64__
</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;'>+ * All *stat*() calls on 10.4 ppc64 usually return garbage in the tv_nsec
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * values of timestamps.  Since sub-second values are not actually supported
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * in this OS version, the fix is simply to add wrappers that clear all
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * tv_nsec values in the results.
</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;'>+/* Clear all tv_nsec values in the structure */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fix_stat(struct stat *buf)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  buf->st_atimespec.tv_nsec = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  buf->st_mtimespec.tv_nsec = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  buf->st_ctimespec.tv_nsec = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Note that the non-ino64 version has no birthtime. */
</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;'>+/* Now all the wrapper functions */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+stat(const char *path, struct stat *buf)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  GET_OS_FUNC(stat)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ret = (*os_stat)(path, buf);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!ret) fix_stat(buf);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return ret;
</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;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+lstat(const char *path, struct stat *buf)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  GET_OS_FUNC(lstat)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ret = (*os_lstat)(path, buf);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!ret) fix_stat(buf);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return ret;
</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;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fstat(int fildes, struct stat *buf)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  GET_OS_FUNC(fstat)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ret = (*os_fstat)(fildes, buf);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!ret) fix_stat(buf);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return ret;
</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;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Since Rosetta (ppc) and ppc64 are mutually exclusive, we don't need
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * to worry about conflicts in the *statx_np() functions.
</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;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+statx_np(const char *path, 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;'>+  int ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  GET_OS_FUNC(statx_np)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ret = (*os_statx_np)(path, buf, fsec);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!ret) fix_stat(buf);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return ret;
</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;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+lstatx_np(const char *path, 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;'>+  int ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  GET_OS_FUNC(lstatx_np)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ret = (*os_lstatx_np)(path, buf, fsec);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!ret) fix_stat(buf);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return ret;
</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;'>+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;'>+  int ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  GET_OS_FUNC(fstatx_np)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ret = (*os_fstatx_np)(fildes, buf, fsec);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!ret) fix_stat(buf);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return ret;
</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_PPC64__ */
</span> 
 #if __MPLS_LIB_FIX_TIGER_ROSETTA__
 /*
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -91,21 +201,18 @@ struct stat64 __DARWIN_STRUCT_STAT64;
</span>  * Note that we only need to provide the basic variant, since the wrappers
  * providing the additional variants will call this version.
  *
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * 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:#ffe0e0;'>- * 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;'>+ * Also note that chmodx_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 unknown, and hence there's no fix provided.  It's known *not*
</span>  * to be a simple byte-swapping issue.
  */
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#include <dlfcn.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stddef.h>
</span> 
 #include <sys/sysctl.h>
 #include <sys/types.h>
 
 #include <libkern/OSByteOrder.h>
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#include "compiler.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> /* sysctl to check whether we're running natively (non-ppc only) */
 #define SYSCTL_NATIVE "sysctl.proc_native"
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -133,25 +240,19 @@ is_tiger_rosetta(void)
</span> int
 fstatx_np(int fildes, struct stat *buf, filesec_t fsec)
 {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-  static __typeof__(fstatx_np) *fstatx = NULL;
</span>   static int tiger_rosetta = 0;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+  GET_OS_FUNC(fstatx_np)
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-  if (MPLS_SLOWPATH(!fstatx)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (!(fstatx = dlsym(RTLD_NEXT, "fstatx_np"))) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-      /* Something's badly wrong if we can't find the function */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-      abort();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  }
</span>   /* If known not 10.4 Rosetta or NULL fsec, just call the function normally */
   if (MPLS_FASTPATH(tiger_rosetta < 0 || fsec == NULL)) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    return (*fstatx)(fildes, buf, fsec);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return (*os_fstatx_np)(fildes, buf, fsec);
</span>   }
 
   /* If we don't yet know the Rosetta status, get it */
   if (!tiger_rosetta) tiger_rosetta = is_tiger_rosetta();
 
   /* Iff it's 10.4 Rosetta, byte-swap the fd */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-  return (*fstatx)(tiger_rosetta >= 0 ? OSSwapInt32(fildes) : fildes,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return (*os_fstatx_np)(tiger_rosetta >= 0 ? OSSwapInt32(fildes) : fildes,
</span>                    buf, fsec);
 }
 
</pre><pre style='margin:0'>

</pre>