POSIX:2024 <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_un.h.html> specifies that <sys/un.h> should define the sa_family_t type.
This patch ensures it. 2025-01-10 Bruno Haible <br...@clisp.org> sys_un-h: Ensure that <sys/un.h> defines sa_family_t. * lib/sys_un.in.h: Include <sys/socket.h> or define sa_family_t explicitly. * m4/sys_socket_h.m4 (gl_PREREQ_SYS_SA_FAMILY): New macro, extracted from gl_SYS_SOCKET_H. (gl_SYS_SOCKET_H): Invoke it. (gl_SYS_SOCKET_H_DEFAULTS): Don't initialize HAVE_SA_FAMILY_T. * m4/sys_un_h.m4 (gl_SYS_UN_H): Invoke gl_PREREQ_SYS_SA_FAMILY. Test whether <sys/un.h> defines sa_family_t. If not, set GL_GENERATE_SYS_UN_H to true. * modules/sys_un-h (Makefile.am): Substitute HAVE_SA_FAMILY_T, HAVE_SA_FAMILY_T_IN_SYS_UN_H. * tests/test-sys_un-h.c: Include intprops.h. Verify that sa_family_t is defined and an unsigned integer type. * modules/sys_un-h-tests (Depends-on): Add intprops. * doc/posix-headers/sys_un.texi: Mention the problem with sa_family_t. diff --git a/doc/posix-headers/sys_un.texi b/doc/posix-headers/sys_un.texi index 63be81d8d2..338f5826c8 100644 --- a/doc/posix-headers/sys_un.texi +++ b/doc/posix-headers/sys_un.texi @@ -14,6 +14,9 @@ @c <https://blogs.windows.com/windows-insider/2017/12/19/announcing-windows-10-insider-preview-build-17063-pc/> This header file is missing on some platforms: mingw, MSVC 14. +@item +This header file does not define the @code{sa_family_t} type on some platforms: +Cygwin 3.5.5, mingw, MSVC 14. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/sys_un.in.h b/lib/sys_un.in.h index e2ffcc6c6f..a32444a253 100644 --- a/lib/sys_un.in.h +++ b/lib/sys_un.in.h @@ -60,5 +60,25 @@ #endif +#if !@HAVE_SA_FAMILY_T_IN_SYS_UN_H@ +# if @HAVE_SA_FAMILY_T@ +/* A platform that has <sys/un.h> but which — unlike <sys/socket.h> — does not + define the 'sa_family_t' type. */ +# include <sys/socket.h> +# else +/* A platform which does not define the 'sa_family_t' type at all. + Define it here in the same way as in <sys/socket.h>. */ +# if !GNULIB_defined_sa_family_t +/* On OS/2 kLIBC, sa_family_t is unsigned char unless TCPV40HDRS is defined. */ +# if !defined __KLIBC__ || defined TCPV40HDRS +typedef unsigned short sa_family_t; +# else +typedef unsigned char sa_family_t; +# endif +# define GNULIB_defined_sa_family_t 1 +# endif +# endif +#endif + #endif /* _@GUARD_PREFIX@_SYS_UN_H */ #endif /* _@GUARD_PREFIX@_SYS_UN_H */ diff --git a/m4/sys_socket_h.m4 b/m4/sys_socket_h.m4 index 75e9748572..08b1c6d929 100644 --- a/m4/sys_socket_h.m4 +++ b/m4/sys_socket_h.m4 @@ -1,5 +1,5 @@ # sys_socket_h.m4 -# serial 29 +# serial 30 dnl Copyright (C) 2005-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -53,24 +53,10 @@ AC_DEFUN_ONCE([gl_SYS_SOCKET_H] fi # We need to check for ws2tcpip.h now. gl_PREREQ_SYS_H_SOCKET - AC_CHECK_TYPES([struct sockaddr_storage, sa_family_t],,,[ - /* sys/types.h is not needed according to POSIX, but the - sys/socket.h in i386-unknown-freebsd4.10 and - powerpc-apple-darwin5.5 required it. */ -#include <sys/types.h> -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_WS2TCPIP_H -#include <ws2tcpip.h> -#endif -]) if test $ac_cv_type_struct_sockaddr_storage = no; then HAVE_STRUCT_SOCKADDR_STORAGE=0 fi - if test $ac_cv_type_sa_family_t = no; then - HAVE_SA_FAMILY_T=0 - fi + gl_PREREQ_SYS_SA_FAMILY if test $ac_cv_type_struct_sockaddr_storage != no; then AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family], [], @@ -159,6 +145,32 @@ AC_DEFUN([gl_PREREQ_SYS_H_WS2TCPIP] AC_SUBST([HAVE_WS2TCPIP_H]) ]) +# Common prerequisites of the <sys/socket.h> replacement and of the <sys/un.h> +# replacement. +# Sets and substitutes HAVE_SA_FAMILY_T. +AC_DEFUN([gl_PREREQ_SYS_SA_FAMILY], +[ + AC_REQUIRE([gl_CHECK_SOCKET_HEADERS]) + AC_CHECK_TYPES([struct sockaddr_storage, sa_family_t],,,[ + /* sys/types.h is not needed according to POSIX, but the + sys/socket.h in i386-unknown-freebsd4.10 and + powerpc-apple-darwin5.5 required it. */ +#include <sys/types.h> +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_WS2TCPIP_H +#include <ws2tcpip.h> +#endif +]) + if test $ac_cv_type_sa_family_t = yes; then + HAVE_SA_FAMILY_T=1 + else + HAVE_SA_FAMILY_T=0 + fi + AC_SUBST([HAVE_SA_FAMILY_T]) +]) + # gl_SYS_SOCKET_MODULE_INDICATOR([modulename]) # sets the shell variable that indicates the presence of the given module # to a C preprocessor expression that will evaluate to 1. @@ -203,6 +215,5 @@ AC_DEFUN([gl_SYS_SOCKET_H_DEFAULTS] HAVE_STRUCT_SOCKADDR_STORAGE=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE]) HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY]) - HAVE_SA_FAMILY_T=1; AC_SUBST([HAVE_SA_FAMILY_T]) HAVE_ACCEPT4=1; AC_SUBST([HAVE_ACCEPT4]) ]) diff --git a/m4/sys_un_h.m4 b/m4/sys_un_h.m4 index 2990345ebe..7f2ad2e6ca 100644 --- a/m4/sys_un_h.m4 +++ b/m4/sys_un_h.m4 @@ -1,5 +1,5 @@ # sys_un_h.m4 -# serial 2 +# serial 3 dnl Copyright 2024-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -13,6 +13,28 @@ AC_DEFUN_ONCE([gl_SYS_UN_H] dnl Check if UNIX domain sockets are supported. AC_REQUIRE([gl_SOCKET_FAMILY_UNIX]) + gl_PREREQ_SYS_SA_FAMILY + AC_CACHE_CHECK([whether <sys/un.h> defines sa_family_t], + [gl_cv_type_sys_un_sa_family_t], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #include <stddef.h> + #include <string.h> + #include <sys/un.h> + ]], [[ + sa_family_t f; + ]]) + ], + [gl_cv_type_sys_un_sa_family_t=yes], + [gl_cv_type_sys_un_sa_family_t=no]) + ]) + if test $gl_cv_type_sys_un_sa_family_t = yes; then + HAVE_SA_FAMILY_T_IN_SYS_UN_H=1 + else + HAVE_SA_FAMILY_T_IN_SYS_UN_H=0 + fi + AC_SUBST([HAVE_SA_FAMILY_T_IN_SYS_UN_H]) + GL_GENERATE_SYS_UN_H=false if test $gl_cv_socket_unix = yes; then dnl Check if using a Windows version that supports AF_UNIX. @@ -27,6 +49,9 @@ AC_DEFUN_ONCE([gl_SYS_UN_H] *-gnu* | gnu*) GL_GENERATE_SYS_UN_H=true ;; esac fi + if test $HAVE_SA_FAMILY_T_IN_SYS_UN_H = 0; then + GL_GENERATE_SYS_UN_H=true + fi if $GL_GENERATE_SYS_UN_H; then AC_CHECK_HEADERS([sys/un.h]) diff --git a/modules/sys_un-h b/modules/sys_un-h index 3c1b3ba505..8f80b8b4c7 100644 --- a/modules/sys_un-h +++ b/modules/sys_un-h @@ -32,6 +32,8 @@ sys/un.h: sys_un.in.h $(top_builddir)/config.status -e 's|@''HAVE_SYS_UN_H''@|$(HAVE_SYS_UN_H)|g' \ -e 's|@''HAVE_WINSOCK2_H''@|$(HAVE_WINSOCK2_H)|g' \ -e 's|@''HAVE_AFUNIX_H''@|$(HAVE_AFUNIX_H)|g' \ + -e 's|@''HAVE_SA_FAMILY_T''@|$(HAVE_SA_FAMILY_T)|g' \ + -e 's|@''HAVE_SA_FAMILY_T_IN_SYS_UN_H''@|$(HAVE_SA_FAMILY_T_IN_SYS_UN_H)|g' \ $(srcdir)/sys_un.in.h > $@-t $(AM_V_at)mv $@-t $@ else diff --git a/modules/sys_un-h-tests b/modules/sys_un-h-tests index e2e3bf7860..6722ce2bea 100644 --- a/modules/sys_un-h-tests +++ b/modules/sys_un-h-tests @@ -3,6 +3,7 @@ tests/test-sys_un-h.c Depends-on: assert-h +intprops sys_un-h-c++-tests configure.ac: diff --git a/tests/test-sys_un-h.c b/tests/test-sys_un-h.c index 5755f2f935..4eac2742ec 100644 --- a/tests/test-sys_un-h.c +++ b/tests/test-sys_un-h.c @@ -23,6 +23,11 @@ /* Specification. */ # include <sys/un.h> +# include "intprops.h" + +/* POSIX requires that sa_family_t is an unsigned integer type. */ +static_assert (! TYPE_SIGNED (sa_family_t)); + int main (void) {