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 <collin.fu...@gmail.com> 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 <collin.fu...@gmail.com> + + 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 <br...@clisp.org> 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 <collin.fu...@gmail.com> 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 <collin.fu...@gmail.com> + 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