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