POSIX:2024 specifies a number of additions to <sys/socket.h>: <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_socket.h.html>
2025-01-09 Bruno Haible <br...@clisp.org> sys_socket-h: Update for POSIX:2024. * doc/posix-headers/sys_socket.texi: Mention a variety of portability problems. * tests/test-sys_socket-h.c: Check for struct sockaddr, struct sockaddr_storage, struct linger, SOL_SOCKET, SOMAXCONN. Include macros.h. (main): Check the socket types, socket options, and some MSG* constants. * modules/sys_socket-h-tests (Files): Add tests/macros.h. diff --git a/doc/posix-headers/sys_socket.texi b/doc/posix-headers/sys_socket.texi index d6084980ba..9217a27c8d 100644 --- a/doc/posix-headers/sys_socket.texi +++ b/doc/posix-headers/sys_socket.texi @@ -44,4 +44,43 @@ platforms. This can be detected by the absence of the @code{CMSG_FIRSTHDR} macro: gnulib replacement header, old BSD +@item +This header file does not define the macro code{SOCK_NONBLOCK} +on some platforms: +macOS 15, AIX 7.3, Solaris 10, mingw, MSVC 14. +@item +This header file does not define the macros code{SOCK_CLOEXEC} and +@code{MSG_CMSG_CLOEXEC} on some platforms: +macOS 15, AIX 7.3, Solaris 10, mingw, MSVC 14. +@item +This header file does not define the macro code{MSG_CMSG_CLOEXEC} +on some platforms: +Solaris 11 OmniOS. +@item +This header file does not define the macro code{SO_DOMAIN} on some platforms: +macOS 15, NetBSD 10.0, AIX 7.3, Cygwin 3.5, mingw, MSVC 14. +@item +This header file does not define the macro code{SO_PROTOCOL} on some platforms: +macOS 15, NetBSD 10.0, AIX 7.3, Solaris 11.4, Cygwin 3.5, mingw, MSVC 14. +@item +This header file does not define the macro code{MSG_NOSIGNAL} on some platforms: +Solaris 10, mingw, MSVC 14. +@item +This header file does not define the macro code{MSG_EOR} on some platforms: +mingw, MSVC 14. +@item +This header file does not define the macros code{MSG_CTRUNC} and +@code{MSG_TRUNC} on some platforms: +mingw. +@item +This header file does not define the macro code{MSG_WAITALL} on some platforms: +MSVC 14. +@item +This header file does not define the type @code{struct cmsghdr} and +the constant @code{SCM_RIGHTS} on some platforms: +mingw, MSVC 14. +@item +This header file does not define the constants @code{SOCK_CLOFORK} and +@code{MSG_CMSG_CLOFORK} on some platforms: +glibc 2.39, musl libc, macOS, FreeBSD, NetBSD, OpenBSD, AIX, Solaris 11.3, Cygwin, mingw, MSVC, Android. @end itemize diff --git a/modules/sys_socket-h-tests b/modules/sys_socket-h-tests index 4b1f7b8a84..33dcfd9e76 100644 --- a/modules/sys_socket-h-tests +++ b/modules/sys_socket-h-tests @@ -1,5 +1,6 @@ Files: tests/test-sys_socket-h.c +tests/macros.h Depends-on: assert-h diff --git a/tests/test-sys_socket-h.c b/tests/test-sys_socket-h.c index ef17d2a5a0..5644f141a8 100644 --- a/tests/test-sys_socket-h.c +++ b/tests/test-sys_socket-h.c @@ -30,15 +30,38 @@ socklen_t t1; size_t t2; ssize_t t3; +/* Check that the 'struct sockaddr' type is defined. */ +struct sockaddr t4; + +/* Check that the 'struct sockaddr_storage' type is defined. */ +struct sockaddr_storage t5; + /* Check that 'struct iovec' is defined. */ struct iovec io; /* Check that a minimal set of 'struct msghdr' is defined. */ struct msghdr msg; +#ifdef SCM_RIGHTS +/* Check that the 'struct cmsghdr' type is defined. */ +struct cmsghdr cmsg; +/* Check constant cmsg_type values. */ +int cmsg_types[] = { SCM_RIGHTS }; +#endif + +/* Check that the 'struct linger' type is defined. */ +struct linger li; + +/* Check constant level arguments. */ +int levels[] = { SOL_SOCKET }; + +/* Check constant backlog arguments. */ +int backlogs[] = { SOMAXCONN }; + #include <errno.h> #include "intprops.h" +#include "macros.h" /* POSIX requires that 'socklen_t' is an integer type with a width of at least 32 bits. */ @@ -67,6 +90,104 @@ main (void) break; } + /* Check that the supported socket types have distinct values. */ + switch (0) + { + case SOCK_DGRAM: +#ifdef SOCK_RAW + case SOCK_RAW: +#endif + case SOCK_SEQPACKET: + case SOCK_STREAM: + default: + break; + } + int socket_types = 0; + socket_types |= SOCK_DGRAM; +#ifdef SOCK_RAW + socket_types |= SOCK_RAW; +#endif + socket_types |= SOCK_SEQPACKET; + socket_types |= SOCK_STREAM; + + /* Check socket creation flags. */ +#ifdef SOCK_NONBLOCK + ASSERT ((SOCK_NONBLOCK & socket_types) == 0); +#endif +#ifdef SOCK_CLOEXEC + ASSERT ((SOCK_CLOEXEC & socket_types) == 0); +#endif +#ifdef SOCK_CLOFORK + ASSERT ((SOCK_CLOFORK & socket_types) == 0); +#endif +#if defined SOCK_NONBLOCK && defined SOCK_CLOEXEC + static_assert ((SOCK_NONBLOCK & SOCK_CLOEXEC) == 0); +#endif +#if defined SOCK_NONBLOCK && defined SOCK_CLOFORK + static_assert ((SOCK_NONBLOCK & SOCK_CLOFORK) == 0); +#endif +#if defined SOCK_CLOEXEC && defined SOCK_CLOFORK + static_assert ((SOCK_CLOEXEC & SOCK_CLOFORK) == 0); +#endif + + /* Check that the option_name constants have distinct values. */ + switch (0) + { + case SO_ACCEPTCONN: + case SO_BROADCAST: + case SO_DEBUG: +#ifdef SO_DOMAIN + case SO_DOMAIN: +#endif + case SO_DONTROUTE: + case SO_ERROR: + case SO_KEEPALIVE: + case SO_LINGER: + case SO_OOBINLINE: +#ifdef SO_PROTOCOL + case SO_PROTOCOL: +#endif + case SO_RCVBUF: + case SO_RCVLOWAT: + case SO_RCVTIMEO: + case SO_REUSEADDR: + case SO_SNDBUF: + case SO_SNDLOWAT: + case SO_SNDTIMEO: + case SO_TYPE: + default: + break; + } + + /* Check the msg_flags constants have distinct values. */ + switch (0) + { +#ifdef MSG_CMSG_CLOEXEC + case MSG_CMSG_CLOEXEC: +#endif +#ifdef SOCK_CLOFORK + case MSG_CMSG_CLOFORK: +#endif + case MSG_DONTROUTE: +#ifdef MSG_EOR + case MSG_EOR: +#endif + case MSG_OOB: +#ifdef MSG_NOSIGNAL + case MSG_NOSIGNAL: +#endif + case MSG_PEEK: +#ifdef MSG_TRUNC + case MSG_CTRUNC: + case MSG_TRUNC: +#endif +#ifdef MSG_WAITALL + case MSG_WAITALL: +#endif + default: + break; + } + /* Check that each supported address family has a distinct value. */ switch (0) { @@ -100,6 +221,7 @@ main (void) i = 42; msg.msg_iov = &io; - return (x.ss_family - i + msg.msg_namelen + msg.msg_iov->iov_len - + msg.msg_iovlen); + return (x.ss_family - i + + msg.msg_namelen + msg.msg_iov->iov_len + msg.msg_iovlen) + + test_exit_status; }