<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/9c1d27e93d8134f88bb6e988e12a6332d8c0c3ae">https://github.com/macports/macports-legacy-support/commit/9c1d27e93d8134f88bb6e988e12a6332d8c0c3ae</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'>     new 9c1d27e  Fix dirent.h for C++ (argless seekdir macro clashed with typename)
</span>9c1d27e is described below

<span style='display:block; white-space:pre;color:#808000;'>commit 9c1d27e93d8134f88bb6e988e12a6332d8c0c3ae
</span>Author: raf <raf@raf.org>
AuthorDate: Wed Jul 26 11:34:58 2023 +1000

<span style='display:block; white-space:pre;color:#404040;'>    Fix dirent.h for C++ (argless seekdir macro clashed with typename)
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Co-authored-by: Tavian Barnes <tavianator@tavianator.com>
</span>---
 include/dirent.h                    | 107 ++++++++++++++++----------
 src/fdopendir.c                     |  93 +++++++++++++++-------
 test/test_dirent_with_cplusplus.cpp |  87 +++++++++++++++++++++
 test/test_fdopendir.c               | 148 +++++++++++++++++++++++++++++++++---
 test/test_traverse.c                |  23 +++---
 test/test_traverse_cwd.c            |  23 +++---
 6 files changed, 378 insertions(+), 103 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/include/dirent.h b/include/dirent.h
</span><span style='display:block; white-space:pre;color:#808080;'>index aa9a6d7..b28423f 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/include/dirent.h
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/include/dirent.h
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,7 +1,7 @@
</span> 
 /*
  * Copyright (c) 2019
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Copyright (c) 2023 raf <raf@raf.org>, Tavian Barnes <tavianator@tavianator.com>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (C) 2023 raf <raf@raf.org>, Tavian Barnes <tavianator@tavianator.com>
</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;'>@@ -22,67 +22,96 @@
</span> /* MP support header */
 #include "MacportsLegacySupport.h"
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Alter function names declared by <dirent.h> to get them out of the way */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Note: These renamed names are non-functional */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#if __MP_LEGACY_SUPPORT_FDOPENDIR__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define opendir __mpls_renamed_libc_opendir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define closedir __mpls_renamed_libc_closedir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define readdir __mpls_renamed_libc_readdir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define readdir_r __mpls_renamed_libc_readdir_r
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define rewinddir __mpls_renamed_libc_rewinddir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define seekdir __mpls_renamed_libc_seekdir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define telldir __mpls_renamed_libc_telldir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /* Include the primary system dirent.h */
 #include_next <dirent.h>
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Remove the above macros to make way for the declarations below */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#if __MP_LEGACY_SUPPORT_FDOPENDIR__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef opendir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef closedir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef readdir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef readdir_r
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef rewinddir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef seekdir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef telldir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Fallback to __DARWIN_ALIAS if the other variants are not defined (?) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Note: I don't know if this makes sense */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifdef __DARWIN_ALIAS_I
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  define __MPLS_ALIAS_I(sym) __DARWIN_ALIAS_I(sym)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  define __MPLS_ALIAS_I(sym) __DARWIN_ALIAS(sym)
</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;'>+#ifdef __DARWIN_INODE64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  define __MPLS_INODE64(sym) __DARWIN_INODE64(sym)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#  define __MPLS_INODE64(sym) __DARWIN_ALIAS(sym)
</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;'>+/* Declare alternative names for the underlying functions for use by the wrappers */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Note: Each __MPLS_ALIAS* macro must match the corresponding __DARWIN_ALIAS* in system <dirent.h> */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+DIR *__mpls_libc_opendir(const char *name) __MPLS_ALIAS_I(opendir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int __mpls_libc_closedir(DIR *dir) __MPLS_ALIAS(closedir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+struct dirent *__mpls_libc_readdir(DIR *dir) __MPLS_INODE64(readdir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int __mpls_libc_readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) __MPLS_INODE64(readdir_r);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void __mpls_libc_rewinddir(DIR *dir) __MPLS_ALIAS_I(rewinddir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void __mpls_libc_seekdir(DIR *dir, long loc) __MPLS_ALIAS_I(seekdir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+long __mpls_libc_telldir(DIR *dir) __MPLS_ALIAS_I(telldir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /* fdopendir */
 #if __MP_LEGACY_SUPPORT_FDOPENDIR__
 
 /* Wrapper struct for DIR */
<span style='display:block; white-space:pre;background:#ffe0e0;'>-typedef struct __MP_LEGACY_SUPPORT_DIR __MP_LEGACY_SUPPORT_DIR;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-struct __MP_LEGACY_SUPPORT_DIR {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef struct __MPLS_DIR __MPLS_DIR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+struct __MPLS_DIR {
</span>     DIR *__mpls_dir;
     int __mpls_dirfd;
 };
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#define DIR __MP_LEGACY_SUPPORT_DIR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define DIR __MPLS_DIR
</span> 
 __MP__BEGIN_DECLS
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#ifndef __DARWIN_ALIAS_I
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-extern DIR *fdopendir(int fd) __DARWIN_ALIAS(fdopendir);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-extern DIR *fdopendir(int fd) __DARWIN_ALIAS_I(fdopendir);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+extern DIR *fdopendir(int fd) __MPLS_ALIAS_I(fdopendir);
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-/* Wrapper functions/macros to support fdopendir */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Wrapper functions to support fdopendir */
</span> extern DIR *__mpls_opendir(const char *name);
 extern int __mpls_closedir(DIR *dir);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+extern struct dirent *__mpls_readdir(DIR *dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+extern int __mpls_readdir_r(DIR *dir, struct dirent *entry, struct dirent **result);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+extern void __mpls_rewinddir(DIR *dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+extern void __mpls_seekdir(DIR *dir, long loc);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+extern long __mpls_telldir(DIR *dir);
</span> extern int __mpls_dirfd(DIR *dir);
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#define opendir(name)      __mpls_opendir(name)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#define closedir(dir)      __mpls_closedir(dir)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Define the standard names to refer to LegacySupport's wrappers (via asm renaming) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+DIR *opendir(const char *name) __asm("___mpls_opendir");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int closedir(DIR *dir) __asm("___mpls_closedir");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+struct dirent *readdir(DIR *dir) __asm("___mpls_readdir");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) __asm("___mpls_readdir_r");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void rewinddir(DIR *dir) __asm("___mpls_rewinddir");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+void seekdir(DIR *dir, long loc) __asm("___mpls_seekdir");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+long telldir(DIR *dir) __asm("___mpls_telldir");
</span> 
 #ifndef __MP_LEGACY_SUPPORT_NO_DIRFD_MACRO
 #undef dirfd
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#define dirfd(dir)         __mpls_dirfd(dir)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define dirfd(dir) __mpls_dirfd(dir)
</span> #endif
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-static __inline__ struct dirent *__mpls_readdir(DIR *dir) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    return readdir(dir->__mpls_dir);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-static __inline__ int __mpls_readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    return readdir_r(dir->__mpls_dir, entry, result);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-static __inline__ void __mpls_rewinddir(DIR *dir) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    rewinddir(dir->__mpls_dir);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-static __inline__ void __mpls_seekdir(DIR *dir, long loc) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    seekdir(dir->__mpls_dir, loc);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-static __inline__ long __mpls_telldir(DIR *dir) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    return telldir(dir->__mpls_dir);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#define readdir __mpls_readdir
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#define readdir_r __mpls_readdir_r
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#define rewinddir __mpls_rewinddir
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#define seekdir __mpls_seekdir
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#define telldir __mpls_telldir
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> __MP__END_DECLS
 
 #endif /* __MP_LEGACY_SUPPORT_FDOPENDIR__ */
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/fdopendir.c b/src/fdopendir.c
</span><span style='display:block; white-space:pre;color:#808080;'>index f6c7f46..508670e 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/fdopendir.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/fdopendir.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,20 +1,19 @@
</span> 
 /*
  * Copyright (c) 2019
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Copyright (c) 2023 raf <raf@raf.org>, Tavian Barnes <tavianator@tavianator.com>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (C) 2023 raf <raf@raf.org>, Tavian Barnes <tavianator@tavianator.com>
</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:#ffe0e0;'>- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * SUCH DAMAGE.
</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>  */
 
 /* MP support header */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -30,8 +29,6 @@
</span> #include <sys/errno.h>
 
 #undef DIR
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#undef opendir
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-#undef closedir
</span> 
 
 /*
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -44,26 +41,26 @@
</span>  * deallocated by __mpls_closedir() (see closedir() macro in <dirent.h>).
  */
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-__MP_LEGACY_SUPPORT_DIR *fdopendir(int dirfd) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+__MPLS_DIR *fdopendir(int dirfd) {
</span> 
     /* Check dirfd here (for macos-10.4, see _ATCALL() and best_fchdir()) */
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (dirfd != AT_FDCWD && dirfd < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (dirfd < 0) {
</span>         errno = EBADF;
         return 0;
     }
 
     /* Open the supplied directory safely */
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    DIR *dir = _ATCALL(dirfd, ".", NULL, opendir("."));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    DIR *dir = _ATCALL(dirfd, ".", NULL, __mpls_libc_opendir("."));
</span>     if (!dir)
         return 0;
 
     /* Wrap it and return it (with the supplied directory file descriptor) */
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    __MP_LEGACY_SUPPORT_DIR *mplsdir = malloc(sizeof(*mplsdir));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    __MPLS_DIR *mplsdir = malloc(sizeof(*mplsdir));
</span>     if (!mplsdir) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        (void)closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        (void)__mpls_libc_closedir(dir);
</span>         errno = ENOMEM;
         return 0;
     }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -81,15 +78,15 @@ __MP_LEGACY_SUPPORT_DIR *fdopendir(int dirfd) {
</span>  * deallocated by __mpls_closedir() (see closedir() macro in <dirent.h>).
  */
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-__MP_LEGACY_SUPPORT_DIR *__mpls_opendir(const char *name) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+__MPLS_DIR *__mpls_opendir(const char *name) {
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    DIR *dir = opendir(name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    DIR *dir = __mpls_libc_opendir(name);
</span>     if (!dir)
         return 0;
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    __MP_LEGACY_SUPPORT_DIR *mplsdir = malloc(sizeof(*mplsdir));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    __MPLS_DIR *mplsdir = malloc(sizeof(*mplsdir));
</span>     if (!mplsdir) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        (void)closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        (void)__mpls_libc_closedir(dir);
</span>         errno = ENOMEM;
         return 0;
     }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -108,16 +105,16 @@ __MP_LEGACY_SUPPORT_DIR *__mpls_opendir(const char *name) {
</span>  * __mpls_opendir().
  */
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-int __mpls_closedir(__MP_LEGACY_SUPPORT_DIR *mplsdir) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int __mpls_closedir(__MPLS_DIR *mplsdir) {
</span> 
     if (!mplsdir) {
         errno = EBADF;
         return -1;
     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    int rc = closedir(mplsdir->__mpls_dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    int rc = __mpls_libc_closedir(mplsdir->__mpls_dir);
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (mplsdir->__mpls_dirfd != AT_FDCWD && mplsdir->__mpls_dirfd != -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (mplsdir->__mpls_dirfd != -1)
</span>         PROTECT_ERRNO(close(mplsdir->__mpls_dirfd));
 
     free(mplsdir);
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -125,16 +122,56 @@ int __mpls_closedir(__MP_LEGACY_SUPPORT_DIR *mplsdir) {
</span>     return rc;
 }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Wrapped version of readdir() for fdopendir() compatibility.
</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;'>+struct dirent *__mpls_readdir(__MPLS_DIR *mplsdir) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return __mpls_libc_readdir(mplsdir->__mpls_dir);
</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;'>+ * Wrapped version of readdir_r() for fdopendir() compatibility.
</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 __mpls_readdir_r(__MPLS_DIR *mplsdir, struct dirent *entry, struct dirent **result) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return __mpls_libc_readdir_r(mplsdir->__mpls_dir, entry, result);
</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;'>+ * Wrapped version of rewinddir() for fdopendir() compatibility.
</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;'>+void __mpls_rewinddir(__MPLS_DIR *mplsdir) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    __mpls_libc_rewinddir(mplsdir->__mpls_dir);
</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;'>+ * Wrapped version of seekdir() for fdopendir() compatibility.
</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;'>+void __mpls_seekdir(__MPLS_DIR *mplsdir, long loc) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    __mpls_libc_seekdir(mplsdir->__mpls_dir, loc);
</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;'>+ * Wrapped version of telldir() for fdopendir() compatibility.
</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;'>+long __mpls_telldir(__MPLS_DIR *mplsdir) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return __mpls_libc_telldir(mplsdir->__mpls_dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /*
  * Wrapped version of dirfd() for fdopendir() compatibility because dirfd()
  * itself is already a macro (see dirfd() macro in <dirent.h>).
  */
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-int __mpls_dirfd(__MP_LEGACY_SUPPORT_DIR *mplsdir) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int __mpls_dirfd(__MPLS_DIR *mplsdir) {
</span> 
     /* Return the supplied directory file descriptor if there was one */
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if (mplsdir->__mpls_dirfd != AT_FDCWD && mplsdir->__mpls_dirfd != -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (mplsdir->__mpls_dirfd != -1)
</span>         return mplsdir->__mpls_dirfd;
 
     /* Otherwise call the underlying dirfd() macro */
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/test/test_dirent_with_cplusplus.cpp b/test/test_dirent_with_cplusplus.cpp
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..f1f9f0d
</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_dirent_with_cplusplus.cpp
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,87 @@
</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;'>+ * Copyright (C) 2023 raf <raf@raf.org>
</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;'>+ * A recent fix to fdopendir required defining seekdir as a macro to a wrapper
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * function. As it was an argumentless macro, it clashed with the C++ standard
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * library which defines the typename std::ios_base::seekdir. There are other
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * examples of C++ code defining seekdir as an enum type in a similar fashion.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The seekdir macro was changed (for C++ only) to a macro with arguments
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * which prevents the clash.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * This tests the C++ use of the seekdir type in combination with <dirent.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * to make sure that the legacysupport <dirent.h> doesn't break C++ code.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * This test comes from https://en.cppreference.com/w/cpp/io/ios_base/seekdir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * All that is required for this test to pass is that it compile.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * It doesn't matter for the purpose of this project, but the output should
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * look like this:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *  word1 = Hello,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *  word2 = Hello,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *  word3 = World!
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *  word4 = World!
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *  word5 = World!
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *  Note, however, that on my macos-10.6.8 host, the output is:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *  word1 = Hello,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *  word2 = Hello,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *  word3 = World!
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *  word4 = 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *  word5 = 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * But that's the output with or without <dirent.h> so the cause lies
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * elsewhere.
</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;'>+#include <iostream>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sstream>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <dirent.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int main()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    std::istringstream in("Hello, World!");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    std::string word1, word2, word3, word4, word5;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    std::ios_base::seekdir begdir = std::ios_base::beg;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    std::ios_base::seekdir curdir = std::ios_base::cur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    std::ios_base::seekdir enddir = std::ios_base::end;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    in >> word1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    in.seekg(0, begdir); // <- rewind
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    in >> word2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    in.seekg(1, curdir); // -> seek from cur pos toward the end
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    in >> word3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    in.seekg(-6, curdir); // <- seek from cur pos (end) toward begin
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    in >> word4;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    in.seekg(-6, enddir); // <- seek from end toward begin
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    in >> word5;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    std::cout << "word1 = " << word1 << '\n'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+              << "word2 = " << word2 << '\n'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+              << "word3 = " << word3 << '\n'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+              << "word4 = " << word4 << '\n'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+              << "word5 = " << word5 << '\n';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</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;color:#808080;'>diff --git a/test/test_fdopendir.c b/test/test_fdopendir.c
</span><span style='display:block; white-space:pre;color:#808080;'>index a83d7e6..d2fa671 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/test/test_fdopendir.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/test/test_fdopendir.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,7 +1,7 @@
</span> 
 /*
  * Copyright (c) 2019
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Copyright (c) 2023 raf <raf@raf.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (C) 2023 raf <raf@raf.org>
</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;'>@@ -22,7 +22,6 @@
</span> #include <sys/types.h>
 #include <sys/errno.h>
 #include <unistd.h>
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#include <limits.h>
</span> #include <fcntl.h>
 #include <stdio.h>
 #include <string.h>
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -34,50 +33,175 @@ int main() {
</span>     struct dirent *entry;
     int dfd = -1;
     DIR *dir;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    char *first_entry = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    /* Test fdopendir with a valid directory fd, then use readdir */
</span> 
     dfd = open(".", O_RDONLY);
     dir = fdopendir(dfd);
     if (!dir) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        printf("error: fdopendir failed\n");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        printf("dfd: %i\n", dfd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        perror("error: fdopendir failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        fprintf(stderr, "dfd=%i\n", dfd);
</span>         return 1;
     }
 
     while ((entry = readdir(dir))) {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>         if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
             continue;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (!first_entry)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            first_entry = strdup(entry->d_name); /* Remember for rewinddir test later */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (!first_entry) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            perror("error: strdup failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            (void)closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>         if (fstatat(dfd, entry->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            printf("error: fstatat failed on %s\n", entry->d_name);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            printf("dfd: %i\n", dfd);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            close(dfd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            perror("error: fstatat after fdopendir failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            fprintf(stderr, "dfd=%i d_name=%s\n", dfd, entry->d_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            free(first_entry);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            (void)closedir(dir);
</span>             return 1;
         }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> #if FEEDBACK
         printf("%s\n", entry->d_name);
 #endif
     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    close(dfd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    /* Test wrapper functions/macros (all but readdir_r which is deprecated) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    int dfd2 = dirfd(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (dfd2 != dfd) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        fprintf(stderr, "error: dirfd failed: %d != %d\n", dfd2, dfd);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        free(first_entry);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        (void)closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return 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;'>+    rewinddir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    long loc = telldir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (loc < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        perror("error: telldir failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        free(first_entry);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        (void)closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return 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;'>+    if (first_entry) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        int found_first = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</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:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if (strcmp(entry->d_name, first_entry)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                fprintf(stderr, "error: rewinddir failed: readdir %s != %s\n", entry->d_name, first_entry);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                free(first_entry);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                (void)closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return 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;'>+            found_first = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            break;
</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 (!found_first) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            fprintf(stderr, "rewinddir failed to rewind\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            free(first_entry);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            (void)closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return 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;'>+    seekdir(dir, loc);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (first_entry) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        int found_first = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</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:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if (strcmp(entry->d_name, first_entry)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                fprintf(stderr, "error: rewinddir/telldir/readdir/seekdir failed: readdir %s != %s\n", entry->d_name, first_entry);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                free(first_entry);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                (void)closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return 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;'>+            found_first = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            break;
</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 (!found_first) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            fprintf(stderr, "seekdir failed to seek\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            free(first_entry);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            (void)closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return 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;'>+    free(first_entry);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    first_entry = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    (void)closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    dir = opendir(".");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (!dir) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        perror("error: opendir(.) failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return 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;'>+    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:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if (fstatat(dfd, entry->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            perror("error: fstatat after opendir failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            fprintf(stderr, "dfd=%i d_name=%s\n", dfd, entry->d_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            (void)closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return 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;'>+    (void)closedir(dir);
</span> 
     /* Try to use fdopendir with stdin - Should fail with ENOTDIR */
 
     if ((dir = fdopendir(STDIN_FILENO))) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        fprintf(stderr, "fdopendir(stdin) should have failed\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        fprintf(stderr, "error: fdopendir(stdin) should have failed\n");
</span>         (void)closedir(dir);
         return 1;
     } else if (errno != ENOTDIR) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        perror("fdopendir(stdin) should have failed with ENOTDIR");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        perror("error: fdopendir(stdin) should have failed with ENOTDIR");
</span>         return 1;
     }
 
     /* Try to use fdopendir with -1 - Should fail with EBADF */
 
     if ((dir = fdopendir(-1))) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        fprintf(stderr, "fdopendir(-1) should have failed\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        fprintf(stderr, "error: fdopendir(-1) should have failed\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        (void)closedir(dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else if (errno != EBADF) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        perror("error: fdopendir(-1) should have failed with EBADF");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return 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;'>+    /* Try to use fdopendir with AT_FDCWD - Should fail with EBADF */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if ((dir = fdopendir(AT_FDCWD))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        fprintf(stderr, "error: fdopendir(AT_FDCWD) should have failed\n");
</span>         (void)closedir(dir);
         return 1;
     } else if (errno != EBADF) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        perror("fdopendir(-1) should have failed with EBADF");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        perror("error: fdopendir(AT_FDCWD) should have failed with EBADF");
</span>         return 1;
     }
 
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/test/test_traverse.c b/test/test_traverse.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 6d94112..4cd4093 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/test/test_traverse.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/test/test_traverse.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,19 +1,18 @@
</span> 
 /*
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Copyright (c) 2023 raf <raf@raf.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (C) 2023 raf <raf@raf.org>
</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:#ffe0e0;'>- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * SUCH DAMAGE.
</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;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 8c01bb4..b7ae360 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,19 +1,18 @@
</span> 
 /*
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Copyright (c) 2023 raf <raf@raf.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (C) 2023 raf <raf@raf.org>
</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:#ffe0e0;'>- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * SUCH DAMAGE.
</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>  */
 
 /*
</pre><pre style='margin:0'>

</pre>