Hi,
I found the following two changes in POSIX 2024 that were not very well
documented in the CHANGE HISTORY section of <unistd.h> [1] [2]:
The <unistd.h> header shall define the symbolic constants O_CLOEXEC
and O_CLOFORK as described in <fcntl.h>.
Inclusion of the <unistd.h> header may make visible all symbols from
the headers <fcntl.h>, ...
This makes sense due to the addition of dup3 and pipe2. But most
systems, including glibc, require the inclusion of fcntl.h for these
flags [3].
I have applied the following two patches to define O_CLOEXEC in unistd.h
and add a test for it. I also documented the platforms that don't behave
like POSIX 2024 using the GitHub CI.
For now, I have ignored O_CLOFORK since I am unsure how many platforms
support it and Gnulib has no workaround for it, unlike O_CLOEXEC.
Collin
[1] https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/unistd.h.html
[2] https://austingroupbugs.net/view.php?id=1906
[3] https://sourceware.org/bugzilla/show_bug.cgi?id=32706
>From 10331a8ba5e9548671907a09eb6d5d7260543c39 Mon Sep 17 00:00:00 2001
From: Collin Funk <[email protected]>
Date: Sun, 16 Feb 2025 12:23:57 -0800
Subject: [PATCH 1/2] unistd-h: Make sure O_CLOEXEC is defined.
* modules/unistd-h (Depends-on): Add fcntl-h.
* lib/unistd.in.h: Include fcntl.h if inclusion of unistd.h does not
define O_CLOEXEC.
* doc/posix-headers/unistd.texi: Document the platforms that do not
define O_CLOEXEC in unistd.h.
---
ChangeLog | 9 +++++++++
doc/posix-headers/unistd.texi | 3 +++
lib/unistd.in.h | 9 ++++++---
modules/unistd-h | 1 +
4 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 1fa41775dc..de21277abe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2025-02-16 Collin Funk <[email protected]>
+
+ unistd-h: Make sure O_CLOEXEC is defined.
+ * modules/unistd-h (Depends-on): Add fcntl-h.
+ * lib/unistd.in.h: Include fcntl.h if inclusion of unistd.h does not
+ define O_CLOEXEC.
+ * doc/posix-headers/unistd.texi: Document the platforms that do not
+ define O_CLOEXEC in unistd.h.
+
2025-02-16 Bruno Haible <[email protected]>
strncasecmp: Add tests.
diff --git a/doc/posix-headers/unistd.texi b/doc/posix-headers/unistd.texi
index 70c9a87154..4481bcfc1a 100644
--- a/doc/posix-headers/unistd.texi
+++ b/doc/posix-headers/unistd.texi
@@ -23,6 +23,9 @@ @node unistd.h
@item
The @code{_exit} function is not declared in this file on some platforms:
mingw.
+@item
+This header file does not define @code{O_CLOEXEC} on some platforms:
+glibc 2.41, FreeBSD 14.0, NetBSD 10.0, OpenBSD 7.5, Solaris 11.4, Cygwin 3.5, mingw, MSVC 14.
@item
Some platforms provide a @code{NULL} macro that cannot be used in arbitrary
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 3f96e10d7e..acabdf8c68 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -95,12 +95,15 @@
# include <stdio.h>
#endif
+/* FreeBSD 14.0, NetBSD 10.0, OpenBSD 7.5, Solaris 11.4, and glibc 2.41
+ do not define O_CLOEXEC in <unistd.h>. */
/* Cygwin 1.7.1 and Android 4.3 declare unlinkat in <fcntl.h>, not in
<unistd.h>. */
/* But avoid namespace pollution on glibc systems. */
-#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \
- && (defined __CYGWIN__ || defined __ANDROID__) \
- && ! defined __GLIBC__
+#if ! defined O_CLOEXEC \
+ || ((@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \
+ && (defined __CYGWIN__ || defined __ANDROID__) \
+ && ! defined __GLIBC__)
# include <fcntl.h>
#endif
diff --git a/modules/unistd-h b/modules/unistd-h
index af7fda5944..1a7376efdb 100644
--- a/modules/unistd-h
+++ b/modules/unistd-h
@@ -15,6 +15,7 @@ include_next
snippet/arg-nonnull
snippet/c++defs
snippet/warn-on-use
+fcntl-h
ssize_t
stddef-h
sys_types-h
--
2.48.1
>From 3b564fec28458688de4337ee5627568ce4dc78b9 Mon Sep 17 00:00:00 2001
From: Collin Funk <[email protected]>
Date: Sun, 16 Feb 2025 12:29:36 -0800
Subject: [PATCH 2/2] unistd-h tests: Check that unistd.h defines O_CLOEXEC.
* tests/test-unistd-h.c: Prefer #error to emitting a syntax error. Check
that O_CLOEXEC is defined.
---
ChangeLog | 4 ++++
tests/test-unistd-h.c | 6 +++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index de21277abe..ba22c1571a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2025-02-16 Collin Funk <[email protected]>
+ unistd-h tests: Check that unistd.h defines O_CLOEXEC.
+ * tests/test-unistd-h.c: Prefer #error to emitting a syntax error. Check
+ that O_CLOEXEC is defined.
+
unistd-h: Make sure O_CLOEXEC is defined.
* modules/unistd-h (Depends-on): Add fcntl-h.
* lib/unistd.in.h: Include fcntl.h if inclusion of unistd.h does not
diff --git a/tests/test-unistd-h.c b/tests/test-unistd-h.c
index d7173956df..fa86969583 100644
--- a/tests/test-unistd-h.c
+++ b/tests/test-unistd-h.c
@@ -30,7 +30,11 @@ int sk[] = { SEEK_CUR, SEEK_END, SEEK_SET };
/* Check that the various *_FILENO macros are defined. */
#if ! (defined STDIN_FILENO \
&& (STDIN_FILENO + STDOUT_FILENO + STDERR_FILENO == 3))
-missing or broken *_FILENO macros
+# error "missing or broken *_FILENO macros"
+#endif
+
+#ifndef O_CLOEXEC
+# error "O_CLOEXEC is not defined"
#endif
/* Check that the types are all defined. */
--
2.48.1