On 2025-09-01 12:06, Collin Funk wrote:
Bruno Haible via Gnulib discussion list <[email protected]> writes:
AT_FDCWD has been -1 on Haiku for many years, and has been changed
to -100 only recently:
https://cgit.haiku-os.org/haiku/commit/headers/posix/fcntl.h?id=b8caef69155fbe87def579305622b9718d7779dc

The *at tests still fail on Haiku, from what I remember. But I did not
know about this change, thanks.

I thought about fixing it, but it is quite a chore. And I couldn't find
the motivation to do so since I do not use Haiku.

Thanks for letting me know. I did an obvious part of that chore by installing the attached. This also mentions Haiku in the manual. Although I don't use Haiku either, we might as well be POSIX clean here.
From 8ba0c4da1ea978b770d1bbf8e306396ed556205f Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Mon, 1 Sep 2025 13:04:21 -0700
Subject: [PATCH] tests: adapt AT_FDCWD fix for more tests

* tests/test-areadlinkat-with-size.c (main):
* tests/test-areadlinkat.c (main):
* tests/test-faccessat.c (main):
* tests/test-fchmodat.c (main):
* tests/test-fchownat.c (main):
* tests/test-fstatat.c (main):
* tests/test-linkat.c (main):
* tests/test-mkdirat.c (main):
* tests/test-mkfifoat.c (main):
* tests/test-openat-safer.c (main):
* tests/test-readlinkat.c (main):
* tests/test-renameat.c (main):
* tests/test-renameatu.c (main):
* tests/test-symlinkat.c (main):
* tests/test-unlinkat.c (main):
* tests/test-utimensat.c (main):
Work even if AT_FDCWD == -1.
---
 ChangeLog                          | 21 +++++++++++++++++++--
 doc/posix-headers/fcntl.texi       | 11 ++++++-----
 tests/test-areadlinkat-with-size.c |  3 ++-
 tests/test-areadlinkat.c           |  2 +-
 tests/test-faccessat.c             |  2 +-
 tests/test-fchmodat.c              |  2 +-
 tests/test-fchownat.c              |  3 ++-
 tests/test-fstatat.c               |  2 +-
 tests/test-linkat.c                |  5 +++--
 tests/test-mkdirat.c               |  2 +-
 tests/test-mkfifoat.c              |  2 +-
 tests/test-openat-safer.c          |  4 ++--
 tests/test-readlinkat.c            |  3 ++-
 tests/test-renameat.c              |  5 +++--
 tests/test-renameatu.c             |  6 ++++--
 tests/test-symlinkat.c             |  2 +-
 tests/test-unlinkat.c              |  2 +-
 tests/test-utimensat.c             |  2 +-
 18 files changed, 52 insertions(+), 27 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0e3d2c7f1e..d8950512db 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,24 @@
 2025-09-01  Paul Eggert  <[email protected]>
 
-	openat2-tests: fix AT_FDCWD portability
-	* tests/test-openat.c (main): Work even if AT_FDCWD == -1.
+	tests: more fixes for AT_FDCWD portability
+	* tests/test-areadlinkat-with-size.c (main):
+	* tests/test-areadlinkat.c (main):
+	* tests/test-faccessat.c (main):
+	* tests/test-fchmodat.c (main):
+	* tests/test-fchownat.c (main):
+	* tests/test-fstatat.c (main):
+	* tests/test-linkat.c (main):
+	* tests/test-mkdirat.c (main):
+	* tests/test-mkfifoat.c (main):
+	* tests/test-openat.c (main):
+	* tests/test-openat-safer.c (main):
+	* tests/test-readlinkat.c (main):
+	* tests/test-renameat.c (main):
+	* tests/test-renameatu.c (main):
+	* tests/test-symlinkat.c (main):
+	* tests/test-unlinkat.c (main):
+	* tests/test-utimensat.c (main):
+	Work even if AT_FDCWD == -1.
 
 2025-08-31  Collin Funk  <[email protected]>
 
diff --git a/doc/posix-headers/fcntl.texi b/doc/posix-headers/fcntl.texi
index 354bae0193..16ea70cadb 100644
--- a/doc/posix-headers/fcntl.texi
+++ b/doc/posix-headers/fcntl.texi
@@ -151,9 +151,10 @@ mingw, MSVC 14.
 defined on some platforms.
 
 @item
-POSIX allows @samp{AT_FDCWD} to be @minus{}1.
-Even though @samp{AT_FDCWD} is less than @minus{}1 on all
-known practical platforms,
-it is better to not assume that @minus{}1 is an invalid argument
-to functions like @samp{openat}.
+POSIX allows @samp{AT_FDCWD} to be @minus{}1, so it is unsafe to use
+@samp{AT_FDCWD} as an invalid directory file descriptor argument to
+functions like @samp{openat}.
+Instead, you can use @samp{AT_FDCWD == -1 ? -2 : -1}.
+@samp{AT_FDCWD} is @minus{}1 on some platforms:
+Haiku R1/Beta4.
 @end itemize
diff --git a/tests/test-areadlinkat-with-size.c b/tests/test-areadlinkat-with-size.c
index 2fd7c7d004..89f9acf1cd 100644
--- a/tests/test-areadlinkat-with-size.c
+++ b/tests/test-areadlinkat-with-size.c
@@ -73,7 +73,8 @@ main (void)
       ASSERT (strcmp (buf, "nowhere") == 0);
       free (buf);
       errno = 0;
-      ASSERT (areadlinkat_with_size (-1, BASE "link", 1) == NULL);
+      ASSERT (areadlinkat_with_size (AT_FDCWD == -1 ? -2 : -1, BASE "link", 1)
+              == NULL);
       ASSERT (errno == EBADF);
       errno = 0;
       ASSERT (areadlinkat_with_size (AT_FDCWD, BASE "link", 1) == NULL);
diff --git a/tests/test-areadlinkat.c b/tests/test-areadlinkat.c
index 503304a56d..1fea12faf5 100644
--- a/tests/test-areadlinkat.c
+++ b/tests/test-areadlinkat.c
@@ -73,7 +73,7 @@ main (void)
       ASSERT (strcmp (buf, "nowhere") == 0);
       free (buf);
       errno = 0;
-      ASSERT (areadlinkat (-1, BASE "link") == NULL);
+      ASSERT (areadlinkat (AT_FDCWD == -1 ? -2 : -1, BASE "link") == NULL);
       ASSERT (errno == EBADF);
       errno = 0;
       ASSERT (areadlinkat (AT_FDCWD, BASE "link") == NULL);
diff --git a/tests/test-faccessat.c b/tests/test-faccessat.c
index c48900e5a3..1f509a0bea 100644
--- a/tests/test-faccessat.c
+++ b/tests/test-faccessat.c
@@ -34,7 +34,7 @@ main (void)
   /* Test behaviour for invalid file descriptors.  */
   {
     errno = 0;
-    ASSERT (faccessat (-1, "foo", F_OK, 0) == -1);
+    ASSERT (faccessat (AT_FDCWD == -1 ? -2 : -1, "foo", F_OK, 0) == -1);
     ASSERT (errno == EBADF);
   }
   {
diff --git a/tests/test-fchmodat.c b/tests/test-fchmodat.c
index 05a86b6fb4..4805c2742b 100644
--- a/tests/test-fchmodat.c
+++ b/tests/test-fchmodat.c
@@ -36,7 +36,7 @@ main (void)
   /* Test behaviour for invalid file descriptors.  */
   {
     errno = 0;
-    ASSERT (fchmodat (-1, "foo", 0600, 0) == -1);
+    ASSERT (fchmodat (AT_FDCWD == -1 ? -2 : -1, "foo", 0600, 0) == -1);
     ASSERT (errno == EBADF);
   }
   {
diff --git a/tests/test-fchownat.c b/tests/test-fchownat.c
index 6e8d1568dc..c2cc26f55e 100644
--- a/tests/test-fchownat.c
+++ b/tests/test-fchownat.c
@@ -78,7 +78,8 @@ main (_GL_UNUSED int argc, char *argv[])
   /* Test behaviour for invalid file descriptors.  */
   {
     errno = 0;
-    ASSERT (fchownat (-1, "foo", getuid (), getgid (), 0) == -1);
+    ASSERT (fchownat (AT_FDCWD == -1 ? -2 : -1, "foo", getuid (), getgid (), 0)
+            == -1);
     ASSERT (errno == EBADF);
   }
   {
diff --git a/tests/test-fstatat.c b/tests/test-fstatat.c
index 05e5818372..2283de8e96 100644
--- a/tests/test-fstatat.c
+++ b/tests/test-fstatat.c
@@ -83,7 +83,7 @@ main (_GL_UNUSED int argc, _GL_UNUSED char *argv[])
     struct stat statbuf;
 
     errno = 0;
-    ASSERT (fstatat (-1, "foo", &statbuf, 0) == -1);
+    ASSERT (fstatat (AT_FDCWD == -1 ? -2 : -1, "foo", &statbuf, 0) == -1);
     ASSERT (errno == EBADF);
   }
   {
diff --git a/tests/test-linkat.c b/tests/test-linkat.c
index 5fd2e37ebf..c115b70744 100644
--- a/tests/test-linkat.c
+++ b/tests/test-linkat.c
@@ -97,7 +97,7 @@ main (void)
   /* Test behaviour for invalid file descriptors.  */
   {
     errno = 0;
-    ASSERT (linkat (-1, "foo", AT_FDCWD, "bar", 0) == -1);
+    ASSERT (linkat (AT_FDCWD == -1 ? -2 : -1, "foo", AT_FDCWD, "bar", 0) == -1);
     ASSERT (errno == EBADF);
   }
   {
@@ -109,7 +109,8 @@ main (void)
   ASSERT (close (creat (BASE "oo", 0600)) == 0);
   {
     errno = 0;
-    ASSERT (linkat (AT_FDCWD, BASE "oo", -1, "bar", 0) == -1);
+    ASSERT (linkat (AT_FDCWD, BASE "oo", AT_FDCWD == -1 ? -2 : -1, "bar", 0)
+            == -1);
     ASSERT (errno == EBADF);
   }
   {
diff --git a/tests/test-mkdirat.c b/tests/test-mkdirat.c
index 162e449460..e1a5630f7d 100644
--- a/tests/test-mkdirat.c
+++ b/tests/test-mkdirat.c
@@ -56,7 +56,7 @@ main (_GL_UNUSED int argc, char *argv[])
   /* Test behaviour for invalid file descriptors.  */
   {
     errno = 0;
-    ASSERT (mkdirat (-1, "foo", 0700) == -1);
+    ASSERT (mkdirat (AT_FDCWD == -1 ? -2 : -1, "foo", 0700) == -1);
     ASSERT (errno == EBADF);
   }
   {
diff --git a/tests/test-mkfifoat.c b/tests/test-mkfifoat.c
index 4c82895a9f..5a13b6fb81 100644
--- a/tests/test-mkfifoat.c
+++ b/tests/test-mkfifoat.c
@@ -91,7 +91,7 @@ main (void)
       /* Test behaviour for invalid file descriptors.  */
       {
         errno = 0;
-        ASSERT (func (-1, "foo", 0600) == -1);
+        ASSERT (func (AT_FDCWD == -1 ? -2 : -1, "foo", 0600) == -1);
         ASSERT (errno == EBADF
                 || errno == ENOSYS /* seen on mingw */
                );
diff --git a/tests/test-openat-safer.c b/tests/test-openat-safer.c
index 8b805c5f29..ca11e260be 100644
--- a/tests/test-openat-safer.c
+++ b/tests/test-openat-safer.c
@@ -84,7 +84,7 @@ main (void)
           ASSERT (openat (dfd, "", O_RDONLY) == -1);
           ASSERT (errno == ENOENT);
           errno = 0;
-          ASSERT (openat (-1, ".", O_RDONLY) == -1);
+          ASSERT (openat (AT_FDCWD == -1 ? -2 : -1, ".", O_RDONLY) == -1);
           ASSERT (errno == EBADF);
 
           /* Check for trailing slash and /dev/null handling.  */
@@ -98,7 +98,7 @@ main (void)
           ASSERT (errno == ENOTDIR || errno == EISDIR || errno == EINVAL);
 #if defined __linux__ || defined __ANDROID__
           /* Using a bad directory is okay for absolute paths.  */
-          fd = openat (-1, "/dev/null", O_WRONLY);
+          fd = openat (AT_FDCWD == -1 ? -2 : -1, "/dev/null", O_WRONLY);
           ASSERT (STDERR_FILENO < fd);
 #endif
           /* Using a non-directory is wrong for relative paths.  */
diff --git a/tests/test-readlinkat.c b/tests/test-readlinkat.c
index 009e2b5fb1..96d806fe4d 100644
--- a/tests/test-readlinkat.c
+++ b/tests/test-readlinkat.c
@@ -61,7 +61,8 @@ main (void)
   /* Test behaviour for invalid file descriptors.  */
   {
     errno = 0;
-    ASSERT (readlinkat (-1, "foo", buf, sizeof buf) == -1);
+    ASSERT (readlinkat (AT_FDCWD == -1 ? -2 : -1, "foo", buf, sizeof buf)
+            == -1);
     ASSERT (errno == EBADF);
   }
   {
diff --git a/tests/test-renameat.c b/tests/test-renameat.c
index f173c7fe7f..f2e1a6198e 100644
--- a/tests/test-renameat.c
+++ b/tests/test-renameat.c
@@ -63,7 +63,7 @@ main (void)
   /* Test behaviour for invalid file descriptors.  */
   {
     errno = 0;
-    ASSERT (renameat (-1, "foo", AT_FDCWD, "bar") == -1);
+    ASSERT (renameat (AT_FDCWD == -1 ? -2 : -1, "foo", AT_FDCWD, "bar") == -1);
     ASSERT (errno == EBADF);
   }
   {
@@ -75,7 +75,8 @@ main (void)
   ASSERT (close (creat (BASE "oo", 0600)) == 0);
   {
     errno = 0;
-    ASSERT (renameat (AT_FDCWD, BASE "oo", -1, "bar") == -1);
+    ASSERT (renameat (AT_FDCWD, BASE "oo", AT_FDCWD == -1 ? -2 : -1, "bar")
+            == -1);
     ASSERT (errno == EBADF);
   }
   {
diff --git a/tests/test-renameatu.c b/tests/test-renameatu.c
index a1e8b97ccc..6841e0875a 100644
--- a/tests/test-renameatu.c
+++ b/tests/test-renameatu.c
@@ -66,7 +66,8 @@ main (void)
   /* Test behaviour for invalid file descriptors.  */
   {
     errno = 0;
-    ASSERT (renameatu (-1, "foo", AT_FDCWD, "bar", 0) == -1);
+    ASSERT (renameatu (AT_FDCWD == -1 ? -2 : -1, "foo", AT_FDCWD, "bar", 0)
+            == -1);
     ASSERT (errno == EBADF);
   }
   {
@@ -78,7 +79,8 @@ main (void)
   ASSERT (close (creat (BASE "oo", 0600)) == 0);
   {
     errno = 0;
-    ASSERT (renameatu (AT_FDCWD, BASE "oo", -1, "bar", 0) == -1);
+    ASSERT (renameatu (AT_FDCWD, BASE "oo", AT_FDCWD == -1 ? -2 : -1, "bar", 0)
+            == -1);
     ASSERT (errno == EBADF);
   }
   {
diff --git a/tests/test-symlinkat.c b/tests/test-symlinkat.c
index 23ca43bdae..f5e20fb23d 100644
--- a/tests/test-symlinkat.c
+++ b/tests/test-symlinkat.c
@@ -60,7 +60,7 @@ main (void)
   /* Test behaviour for invalid file descriptors.  */
   {
     errno = 0;
-    ASSERT (symlinkat ("foo", -1, "bar") == -1);
+    ASSERT (symlinkat ("foo", AT_FDCWD == -1 ? -2 : -1, "bar") == -1);
     ASSERT (errno == EBADF
             || errno == ENOSYS /* seen on mingw */
            );
diff --git a/tests/test-unlinkat.c b/tests/test-unlinkat.c
index bd3f7609f0..ce068f849f 100644
--- a/tests/test-unlinkat.c
+++ b/tests/test-unlinkat.c
@@ -67,7 +67,7 @@ main ()
   /* Test behaviour for invalid file descriptors.  */
   {
     errno = 0;
-    ASSERT (unlinkat (-1, "foo", 0) == -1);
+    ASSERT (unlinkat (AT_FDCWD == -1 ? -2 : -1, "foo", 0) == -1);
     ASSERT (errno == EBADF);
   }
   {
diff --git a/tests/test-utimensat.c b/tests/test-utimensat.c
index 4c6b21b120..8a32f53b78 100644
--- a/tests/test-utimensat.c
+++ b/tests/test-utimensat.c
@@ -71,7 +71,7 @@ main (void)
   /* Test behaviour for invalid file descriptors.  */
   {
     errno = 0;
-    ASSERT (utimensat (-1, "foo", NULL, 0) == -1);
+    ASSERT (utimensat (AT_FDCWD == -1 ? -2 : -1, "foo", NULL, 0) == -1);
     ASSERT (errno == EBADF);
   }
   {
-- 
2.48.1

Reply via email to