<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/dad0a2fee82bed2effb02b9f1b3155dd94479051">https://github.com/macports/macports-legacy-support/commit/dad0a2fee82bed2effb02b9f1b3155dd94479051</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit dad0a2fee82bed2effb02b9f1b3155dd94479051
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Sat Jan 18 21:45:57 2025 -0800

<span style='display:block; white-space:pre;color:#404040;'>    Add test for pthread_[f]chdir_np().
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    This verifies both that the functions set the subthread's cwd as
</span><span style='display:block; white-space:pre;color:#404040;'>    intended, and that the main thread's cwd is unchanged.
</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 on all platforms.
</span><span style='display:block; white-space:pre;color:#404040;'>    Spot-checked test sensitivity with manually introduced bug.
</span>---
 test/test_pthread_chdir.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 227 insertions(+)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/test/test_pthread_chdir.c b/test/test_pthread_chdir.c
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..f114735
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/test/test_pthread_chdir.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,227 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 2025 Frederick H. G. Wright II <fw@fwright.net>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Permission to use, copy, modify, and distribute this software for any
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * purpose with or without fee is hereby granted, provided that the above
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * copyright notice and this permission notice appear in all copies.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
</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;'>+ * This provides tests of the pthtread_chdir_np() and pthread_fchdir_np()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * functions.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The general approach is to use comparisions of stat structures to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * determine whether files or directories are the same.  This is used
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * both to verify that changing the cwd in the test thread doesn't
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * affect the cwd in the main thread, and also that accesses relative
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * to the new cwd are as expected.
</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 !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    || __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <libgen.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdio.h>
</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;'>+main(int argc, char *argv[])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  (void) argc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  printf("%s is unsupported on 10.4\n", basename(argv[0]));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return 0;
</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;'>+#else /* Not 10.4 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Enable the prototypes */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define _MACPORTS_LEGACY_PTHREAD_CHDIR 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <errno.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <fcntl.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <libgen.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <pthread.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdio.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <string.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <unistd.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/stat.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef struct info_s {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char *argv0, *progname, *progdir;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int cwd_fd, progdir_fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int done, stop, chdir_errno, progdir_errno, progname_errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  struct stat cwd_sb, progdir_sb, progname_sb;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  struct stat test_cwd_sb, test_progdir_sb, test_progname_sb;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} info_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef void *(thread_fn_t)(void *);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+run_thread(thread_fn_t *func, info_t *ip)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int err = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  pthread_t thread;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Start the thread */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ip->done = ip->stop = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (pthread_create(&thread, NULL, func, ip)) return errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Wait for thread to do its stuff */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (!ip->done) usleep(1000);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Now see what our cwd is */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (stat(".", &ip->test_cwd_sb) < 0) err = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Stop the test thread */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ip->stop = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (pthread_join(thread, NULL) && !err) err = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Restore our cwd just in case */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  (void) fchdir(ip->cwd_fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return err;
</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;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+compare_stats(const struct stat *sb1, const struct stat *sb2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (sb1->st_dev != sb2->st_dev) return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (sb1->st_mode != sb2->st_mode) return 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (sb1->st_nlink != sb2->st_nlink) return 3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (sb1->st_ino != sb2->st_ino) return 4;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return 0;
</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;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+check_results(info_t *ip)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int err;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Make sure thread didn't change our cwd */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  err = compare_stats(&ip->cwd_sb, &ip->test_cwd_sb);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (err) return err;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  err = compare_stats(&ip->progdir_sb, &ip->test_progdir_sb);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (err) return 100 + err;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  err = compare_stats(&ip->progname_sb, &ip->test_progname_sb);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (err) return 200 + err;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return 0;
</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;'>+static void *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+test_chdir(void *arg)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  info_t *ip = (info_t *) arg;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ip->chdir_errno = ip->progdir_errno = ip->progname_errno = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Do the actual test operation */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (pthread_chdir_np(ip->progdir)) ip->chdir_errno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Collect the stats from the test dir & name */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (stat(".", &ip->test_progdir_sb) < 0) ip->progdir_errno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (stat(ip->progname, &ip->test_progname_sb) < 0) ip->progname_errno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Tell caller we're finished, and wait to be stopped */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ip->done = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (!ip->stop) usleep(1000);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return NULL;
</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;'>+static void *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+test_fchdir(void *arg)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  info_t *ip = (info_t *) arg;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ip->chdir_errno = ip->progdir_errno = ip->progname_errno = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Do the actual test operation */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (pthread_fchdir_np(ip->progdir_fd)) ip->chdir_errno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Collect the stats from the test dir & name */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (stat(".", &ip->test_progdir_sb) < 0) ip->progdir_errno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (stat(ip->progname, &ip->test_progname_sb) < 0) ip->progname_errno = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Tell caller we're finished, and wait to be stopped */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ip->done = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (!ip->stop) usleep(1000);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return NULL;
</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;'>+main(int argc, char *argv[])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int verbose = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int err, ret = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  info_t info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (argc > 1 && !strcmp(argv[1], "-v")) verbose = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!(info.argv0 = strdup(argv[0]))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      || !(info.progname = strdup(basename(argv[0])))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      || !(info.progdir = strdup(dirname(argv[0])))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("Can't copy program name");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 20;
</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 (verbose) printf("%s starting.\n", info.progname);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Collect initial information */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (stat(info.argv0, &info.progname_sb) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("Can't stat program");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 20;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if ((info.cwd_fd = open(".", O_RDONLY)) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("Can't open cwd");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 20;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (fstat(info.cwd_fd, &info.cwd_sb) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("Can't stat cwd");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 20;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if ((info.progdir_fd = open(info.progdir, O_RDONLY)) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("Can't open program's dir");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 20;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (fstat(info.progdir_fd, &info.progdir_sb) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    perror("Can't stat program's dir");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 20;
</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;'>+  /* Do the chdir test */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (verbose) printf("  Testing pthread_chdir_np()\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  err = run_thread(test_chdir, &info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (err) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("  some test operation failed: %s\n", strerror(err));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    err = check_results(&info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (err) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("  mismatched stat after pthread_chdir_np(), code = %d\n", err);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      ret = 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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Do the fchdir test */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (verbose) printf("  Testing pthread_fchdir_np()\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  err = run_thread(test_fchdir, &info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (err) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("  some test operation failed: %s\n", strerror(err));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    err = check_results(&info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (err) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("  mismatched stat after pthread_fchdir_np(), code = %d\n", err);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      ret = 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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  printf("%s %s\n", info.progname, ret ? "failed" : "passed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  free(info.argv0); free(info.progname); free(info.progdir);
</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 /* Not 10.4 */
</span></pre><pre style='margin:0'>

</pre>