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