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