<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/56a9b9e919c6f68ee298032bb31e9f29cae3848f">https://github.com/macports/macports-legacy-support/commit/56a9b9e919c6f68ee298032bb31e9f29cae3848f</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 56a9b9e919c6f68ee298032bb31e9f29cae3848f
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Thu Jul 3 20:04:16 2025 -0700

<span style='display:block; white-space:pre;color:#404040;'>    test_traverse_cwd: Make parallelizable.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Makes created directory name unique.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Also make verbosity optional.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Also adds success/failure message.
</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, including running in parallel.
</span>---
 test/test_traverse_cwd.c | 270 ++++++++++++++++++++++++++++-------------------
 1 file changed, 159 insertions(+), 111 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/test/test_traverse_cwd.c b/test/test_traverse_cwd.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 56a5ae6..9a8caf1 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/test/test_traverse_cwd.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/test/test_traverse_cwd.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,6 +1,6 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> /*
  * Copyright (C) 2023 raf <raf@raf.org>
<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;'>@@ -16,15 +16,17 @@
</span>  */
 
 /*
<span style='display:block; white-space:pre;background:#ffe0e0;'>-Test directory traversal with macports legacysupport.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Test directory traversal with MacPorts legacy-support.
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-This test creates ".test.dir", ".test.dir/subdir" and ".test.dir/subdir/file".
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-It then chdirs into ".test.dir" and then traverses ".".
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This test creates a temporary directory <temp_dir>, <temp_dir>/subdir,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+and <temp_dir>/subdir/file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+It then chdirs into <temp_dir> and then traverses ".".
</span> It then chdirs to ".." afterwards.
<span style='display:block; white-space:pre;background:#ffe0e0;'>-It then deletes ".test.dir" and its contents.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+It then deletes <temp_dir> and its contents.
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-The output should look something like:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The (verbose) output should look something like:
</span> 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+  cd <temp_dir>
</span>   fstatat(parent_fd=-2, .) ok
   openat(parent_fd=-2, .) = dir_fd=3 ok
   fdopendir(dir_fd=3) ok
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -34,8 +36,9 @@ The output should look something like:
</span>   fdopendir(dir_fd=4) ok
   entry file
   fstatat(parent_fd=4, file) ok
<span style='display:block; white-space:pre;background:#ffe0e0;'>-  cwd (before cd ..) /Users/.../macports-legacy-support/.test.dir
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-  cwd (after cd ..)  /Users/.../macports-legacy-support
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  cwd (before cd ..) <test_data_dir>/<temp_dir>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  cwd (after cd ..)  <test_data_dir>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  cd <build_dir>
</span> 
 This differs from test/test_traverse.c which traverses a
 named directory rather than ".". Originally, these
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -43,161 +46,206 @@ exhibited different errors.
</span> 
 */
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <dirent.h>
</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> #include <stdlib.h>
 #include <stdio.h>
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#include <unistd.h>
</span> #include <string.h>
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#include <errno.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#include <fcntl.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#include <dirent.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/param.h>
</span> #include <sys/stat.h>
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-int traverse(int parent_fd, const char *name)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifndef TEST_TEMP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define TEST_TEMP "/dev/null"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static char topdir[MAXPATHLEN];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static char subdir[MAXPATHLEN];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static char testfile[MAXPATHLEN];
</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;'>+traverse(int parent_fd, const char *name, int verbose)
</span> {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    /* Test: fstatat(AT_FDCWD, .test.dir) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int dir_fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  DIR *dir;
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    struct stat statbuf[1];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Test: fstatat(AT_FDCWD, <temp_dir>) */
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (fstatat(parent_fd, name, statbuf, AT_SYMLINK_NOFOLLOW) == -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  struct stat statbuf[1];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (fstatat(parent_fd, name, statbuf, AT_SYMLINK_NOFOLLOW) == -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "fstatat(parent_fd=%d, %s) failed: %s\n", parent_fd, name, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return EXIT_FAILURE;
</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("fstatat(parent_fd=%d, %s) ok\n", parent_fd, name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* If it's a directory, process its entries */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if ((statbuf->st_mode & S_IFMT) == S_IFDIR)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    /* Open it with openat() */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if ((dir_fd = openat(parent_fd, name, O_RDONLY)) == -1)
</span>     {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        fprintf(stderr, "fstatat(parent_fd=%d, %s) failed: %s\n", parent_fd, name, strerror(errno));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return EXIT_FAILURE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      fprintf(stderr, "openat(parent_fd=%d, %s) failed: %s\n", parent_fd, name, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      return EXIT_FAILURE;
</span>     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    printf("fstatat(parent_fd=%d, %s) ok\n", parent_fd, name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (verbose) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("openat(parent_fd=%d, %s) = dir_fd=%d ok\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             parent_fd, name, dir_fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    /* If it's a directory, process its entries */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    /* Open it for traversing with fdopendir() */
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if ((statbuf->st_mode & S_IFMT) == S_IFDIR)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (!(dir = fdopendir(dir_fd)))
</span>     {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        /* Open it with openat() */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        int dir_fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      fprintf(stderr, "fdopendir(dir_fd=%d, dir) failed\n", dir_fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      close(dir_fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      return EXIT_FAILURE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        if ((dir_fd = openat(parent_fd, name, O_RDONLY)) == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            fprintf(stderr, "openat(parent_fd=%d, %s) failed: %s\n", parent_fd, name, strerror(errno));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            return EXIT_FAILURE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (verbose) printf("fdopendir(dir_fd=%d) ok\n", dir_fd);
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        printf("openat(parent_fd=%d, %s) = dir_fd=%d ok\n", parent_fd, name, dir_fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    /* Apply recursively to this directory's entries */
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        /* Open it for traversing with fdopendir() */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    struct dirent *entry;
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        DIR *dir;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while ((entry = readdir(dir)))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        continue;
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        if (!(dir = fdopendir(dir_fd)))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            fprintf(stderr, "fdopendir(dir_fd=%d, dir) failed\n", dir_fd);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            close(dir_fd);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            return EXIT_FAILURE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (verbose) printf("entry %s\n", entry->d_name);
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        printf("fdopendir(dir_fd=%d) ok\n", dir_fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (traverse(dir_fd, entry->d_name, verbose) == EXIT_FAILURE)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return EXIT_FAILURE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        /* Apply recursively to this directory's entries */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        struct dirent *entry;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return EXIT_SUCCESS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        while ((entry = readdir(dir)))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Cleanup */
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            printf("entry %s\n", entry->d_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+cleanup(int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            if (traverse(dir_fd, entry->d_name) == EXIT_FAILURE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                return EXIT_FAILURE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (unlink(testfile) == -1 && !quiet) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "unlink(%s) failed: %s\n", testfile, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        closedir(dir);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (rmdir(subdir) == -1 && !quiet) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "unlink(%s) failed: %s\n", subdir, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    return EXIT_SUCCESS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (rmdir(topdir) == -1 && !quiet) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "unlink(%s) failed: %s\n", topdir, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span> }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-int main(int argc, char **argv)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Setup */
</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;'>+setup(void)
</span> {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    /* Prepare: Create a directory */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int fd;
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    system("rm -rf .test.dir");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  cleanup(1);
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (mkdir(".test.dir", (mode_t)0755) == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        perror("mkdir(.test.dir) failed\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        exit(EXIT_FAILURE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Prepare: Create the top directory */
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    /* And a directory within it */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (mkdir(topdir, (mode_t) 0755) == -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "mkdir(%s) failed: %s\n", topdir, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return EXIT_FAILURE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (mkdir(".test.dir/subdir", (mode_t)0755) == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        perror("mkdir(.test.dir/subdir) failed\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        (void)rmdir(".test.dir");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        exit(EXIT_FAILURE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* And a directory within it */
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    /* And a file within that */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (mkdir(subdir, (mode_t) 0755) == -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "mkdir(%s) failed: %s\n", subdir, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    cleanup(1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return EXIT_FAILURE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    int fd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* And a file within that */
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if ((fd = creat(".test.dir/subdir/file", (mode_t)0644)) == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        perror("creat(.test.dir/subdir/file) failed\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        (void)rmdir(".test.dir/subdir");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        (void)rmdir(".test.dir");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        exit(EXIT_FAILURE);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if ((fd = creat(testfile, (mode_t) 0644)) == -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "creat(%s) failed: %s\n", testfile, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    cleanup(1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return EXIT_FAILURE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    close(fd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  (void) close(fd);
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    /* Test directory traversal */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return EXIT_SUCCESS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    fprintf(stderr, "cd .test.dir\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (chdir(".test.dir") == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        perror("chdir(.test.dir) failed");
</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 rc, verbose = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  pid_t pid = getpid();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char *progname = basename(argv[0]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char cwdbuf0[MAXPATHLEN];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char cwdbuf1[MAXPATHLEN];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char cwdbuf2[MAXPATHLEN];
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    int rc = traverse(AT_FDCWD, ".");
</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:#ffe0e0;'>-    char cwdbuf1[BUFSIZ];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    char cwdbuf2[BUFSIZ];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  (void) snprintf(topdir, sizeof(topdir), TEST_TEMP "/%s-%u", progname, pid);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  (void) snprintf(subdir, sizeof(subdir), "%s/subdir", topdir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  (void) snprintf(testfile, sizeof(testfile), "%s/file", subdir);
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    printf("cwd (before cd ..) %s\n", getcwd(cwdbuf1, BUFSIZ));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  (void) getcwd(cwdbuf0, sizeof(cwdbuf0));
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (chdir("..") == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        perror("chdir .. failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Prepare: Create the directories and file */
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    printf("cwd (after cd ..)  %s\n", getcwd(cwdbuf2, BUFSIZ));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  rc = setup();
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (!strcmp(cwdbuf1, cwdbuf2))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        fprintf(stderr, "Post-traversal chdir(..) silently failed to change directory!\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        fprintf(stderr, "Replacing __mpls_best_fchdir() in fdopendir() with fchdir() fixes this badly.\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        fprintf(stderr, "Using _ATCALL for opendir fixes this properly.\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        rc = EXIT_FAILURE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!rc) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    /* Test directory traversal */
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    /* Cleanup */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (verbose) printf("cd %s\n", topdir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (chdir(topdir) == -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      fprintf(stderr, "chdir(%s) failed: %s\n", topdir, strerror(errno));
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (unlink(".test.dir/subdir/file") == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        perror("unlink .test.dir/subdir/file failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    rc = traverse(AT_FDCWD, ".", verbose);
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (rmdir(".test.dir/subdir") == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        perror("rmdir .test.dir/subdir failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    (void) getcwd(cwdbuf1, sizeof(cwdbuf1));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (verbose) printf("cwd (before cd ..) %s\n", cwdbuf1);
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (rmdir(".test.dir") == -1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        perror("rmdir .test.dir failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (chdir("..") == -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      fprintf(stderr, "chdir(\"..\") failed: %s\n", strerror(errno));
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    /* If the above cleanup didn't work (because chdir .. silently failed to work) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    (void) getcwd(cwdbuf2, sizeof(cwdbuf2));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (verbose) printf("cwd (after cd ..) %s\n", cwdbuf2);
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (!strcmp(cwdbuf1, cwdbuf2))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        fprintf(stderr, "Cleaning up\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        (void)unlink("../.test.dir/subdir/file");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        (void)rmdir("../.test.dir/subdir");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        (void)rmdir("../.test.dir");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (!strcmp(cwdbuf1, cwdbuf2)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      fprintf(stderr, "Post-traversal chdir(..) silently failed to change directory!\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      fprintf(stderr, "Replacing __mpls_best_fchdir() in fdopendir() with fchdir() fixes this badly.\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      fprintf(stderr, "Using _ATCALL for opendir fixes this properly.\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      rc = EXIT_FAILURE;
</span>     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    return rc;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (verbose) printf("cd %s\n", cwdbuf0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (chdir(cwdbuf0) == -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      fprintf(stderr, "chdir(%s) failed: %s\n", cwdbuf0, strerror(errno));
</span> 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    cleanup(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;'>+  printf("%s %s.\n", progname, rc ? "failed" : "passed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return (rc) ? 1 : 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span></pre><pre style='margin:0'>

</pre>