Also, improve errno tests. * m4/calloc.m4 (gl_FUNC_CALLOC_GNU): * m4/malloc.m4 (gl_FUNC_MALLOC_GNU): * m4/realloc.m4 (gl_FUNC_REALLOC_GNU): * m4/scandir.m4 (gl_FUNC_SCANDIR): Define _LINUX_SOURCE_COMPAT, as this can sometimes help on AIX. * m4/errno_h.m4 (gl_HEADER_ERRNO_H): Define _LINUX_SOURCE_COMPAT, to make EEXIST != ENOTEMPTY. * m4/strerror_r.m4 (gl_FUNC_STRERROR_R): Define _LINUX_SOURCE_COMPAT, in case someone else does. * modules/errno-tests (Depends-on): Add assert-h, c99. * tests/test-errno.c (e1, ..., e131): Remove, replacing with ... (CHECK_POSIX_ERRNOS, POSITIVE_INTEGER_CONSTANT_EXPRESSION) (INDEXED_BY_ERRNO, ERRNO_COUNT): These new macros. Check that all errno values are positive integer constant expressions. Check that they are all distinct, except perhaps for EWOULDBLOCK == EAGAIN and ENOTSUP == EOPNOTSUPP. Also check ESOCKTNOSUPPORT, added in POSIX.1-2024. Also, check that errno values are distinct except when POSIX says they needn’t be distinct, since POSIX.1-2024 gives license to GNU/Linux’s non-distinct values. --- ChangeLog | 25 ++++ doc/posix-functions/calloc.texi | 2 +- doc/posix-functions/malloc.texi | 2 +- doc/posix-functions/realloc.texi | 2 +- doc/posix-functions/strerror_r.texi | 3 +- doc/posix-headers/errno.texi | 4 + lib/errno.in.h | 2 +- m4/calloc.m4 | 7 +- m4/errno_h.m4 | 7 +- m4/malloc.m4 | 7 +- m4/passfd.m4 | 4 +- m4/realloc.m4 | 7 +- m4/scandir.m4 | 5 +- m4/strerror_r.m4 | 9 +- modules/errno-tests | 3 +- tests/test-errno.c | 187 +++++++++++++++------------- 16 files changed, 174 insertions(+), 102 deletions(-)
diff --git a/ChangeLog b/ChangeLog index bdedb82c3a..78e4bd2f09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2024-07-31 Paul Eggert <egg...@cs.ucla.edu> + + errno: make EEXIST != ENOTEMPTY on AIX + Also, improve errno tests. + * m4/calloc.m4 (gl_FUNC_CALLOC_GNU): + * m4/malloc.m4 (gl_FUNC_MALLOC_GNU): + * m4/realloc.m4 (gl_FUNC_REALLOC_GNU): + * m4/scandir.m4 (gl_FUNC_SCANDIR): + Define _LINUX_SOURCE_COMPAT, as this can sometimes help on AIX. + * m4/errno_h.m4 (gl_HEADER_ERRNO_H): + Define _LINUX_SOURCE_COMPAT, to make EEXIST != ENOTEMPTY. + * m4/strerror_r.m4 (gl_FUNC_STRERROR_R): + Define _LINUX_SOURCE_COMPAT, in case someone else does. + * modules/errno-tests (Depends-on): Add assert-h, c99. + * tests/test-errno.c (e1, ..., e131): Remove, replacing with ... + (CHECK_POSIX_ERRNOS, POSITIVE_INTEGER_CONSTANT_EXPRESSION) + (INDEXED_BY_ERRNO, ERRNO_COUNT): These new macros. + Check that all errno values are positive integer constant expressions. + Check that they are all distinct, except perhaps for + EWOULDBLOCK == EAGAIN and ENOTSUP == EOPNOTSUPP. + Also check ESOCKTNOSUPPORT, added in POSIX.1-2024. + Also, check that errno values are distinct except when POSIX says + they needn’t be distinct, since POSIX.1-2024 gives license to + GNU/Linux’s non-distinct values. + 2024-07-31 Bruno Haible <br...@clisp.org> float: Update to mostly guarantee ISO C 23 compliance. diff --git a/doc/posix-functions/calloc.texi b/doc/posix-functions/calloc.texi index 20fb026a2f..9e3b5a4929 100644 --- a/doc/posix-functions/calloc.texi +++ b/doc/posix-functions/calloc.texi @@ -30,5 +30,5 @@ It fixes this portability problem: @item @code{calloc (0, s)} and @code{calloc (n, 0)} return @code{NULL} on success on some platforms: -AIX 7.2. +AIX 7.3. @end itemize diff --git a/doc/posix-functions/malloc.texi b/doc/posix-functions/malloc.texi index 2137ba2b81..9ec84fce5d 100644 --- a/doc/posix-functions/malloc.texi +++ b/doc/posix-functions/malloc.texi @@ -27,5 +27,5 @@ by fixing this portability problem: @itemize @item @code{malloc (0)} returns @code{NULL} on success on some platforms: -AIX 7.2. +AIX 7.3. @end itemize diff --git a/doc/posix-functions/realloc.texi b/doc/posix-functions/realloc.texi index 6bb61dd7e4..bd130195c2 100644 --- a/doc/posix-functions/realloc.texi +++ b/doc/posix-functions/realloc.texi @@ -40,7 +40,7 @@ It fixes these portability problems: @itemize @item @code{realloc (NULL, 0)} returns @code{NULL} on success on some platforms: -AIX 7.2. +AIX 7.3. @item On some platforms, @code{realloc (p, 0)} with non-null @code{p} diff --git a/doc/posix-functions/strerror_r.texi b/doc/posix-functions/strerror_r.texi index cff950f963..52f56fcfc5 100644 --- a/doc/posix-functions/strerror_r.texi +++ b/doc/posix-functions/strerror_r.texi @@ -20,7 +20,8 @@ Portability problems fixed by Gnulib: This function is missing on some platforms: NetBSD 3.0, Minix 3.1.8, HP-UX 11.23, Solaris 9, mingw, MSVC 14. @item -glibc, Cygwin, and Android have an incompatible version of this function. +glibc, Cygwin, Android, and AIX+@code{_LINUX_SOURCE_COMPAT} +have an incompatible version of this function. The POSIX compliant code @smallexample char *s = (strerror_r (err, buf, buflen) == 0 ? buf : NULL); diff --git a/doc/posix-headers/errno.texi b/doc/posix-headers/errno.texi index 2adb323d9a..ab8aff39fc 100644 --- a/doc/posix-headers/errno.texi +++ b/doc/posix-headers/errno.texi @@ -53,6 +53,10 @@ Mac OS X 10.5, FreeBSD 6.0, NetBSD 9.3, OpenBSD 6.0, Minix 3.1.8, AIX 5.1, HP-UX @item The macro @code{EILSEQ} is not defined on some platforms: LynxOS 178 2.2.2. +@item +The macros @code{EEXIST} and @code{ENOTEMPTY} have the same value on +some platforms: +AIX 7.3. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/errno.in.h b/lib/errno.in.h index aa658e6270..ba927037f6 100644 --- a/lib/errno.in.h +++ b/lib/errno.in.h @@ -133,7 +133,7 @@ /* These are intentionally the same values as the WSA* error numbers, defined in <winsock2.h>. */ -# define ESOCKTNOSUPPORT 10044 /* not required by POSIX */ +# define ESOCKTNOSUPPORT 10044 # define EPFNOSUPPORT 10046 /* not required by POSIX */ # define ESHUTDOWN 10058 /* not required by POSIX */ # define ETOOMANYREFS 10059 /* not required by POSIX */ diff --git a/m4/calloc.m4 b/m4/calloc.m4 index 550cf5cc90..0fbd0d8090 100644 --- a/m4/calloc.m4 +++ b/m4/calloc.m4 @@ -1,5 +1,5 @@ # calloc.m4 -# serial 31 +# serial 32 dnl Copyright (C) 2004-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -58,6 +58,11 @@ AC_DEFUN([gl_FUNC_CALLOC_GNU], [ AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) AC_REQUIRE([gl_FUNC_CALLOC_POSIX]) + + dnl This helps if !(__VEC__ || __AIXVEC), and shouldn't hurt otherwise. + AC_DEFINE([_LINUX_SOURCE_COMPAT], [1], + [Define so that AIX headers are more compatible with GNU/Linux.]) + REPLACE_CALLOC_FOR_CALLOC_GNU="$REPLACE_CALLOC_FOR_CALLOC_POSIX" if test $REPLACE_CALLOC_FOR_CALLOC_GNU = 0; then _AC_FUNC_CALLOC_IF([], [REPLACE_CALLOC_FOR_CALLOC_GNU=1]) diff --git a/m4/errno_h.m4 b/m4/errno_h.m4 index b6050e5d8e..f6a2e81b5d 100644 --- a/m4/errno_h.m4 +++ b/m4/errno_h.m4 @@ -1,5 +1,5 @@ # errno_h.m4 -# serial 14 +# serial 15 dnl Copyright (C) 2004, 2006, 2008-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -10,6 +10,11 @@ AC_PREREQ([2.61]) AC_DEFUN_ONCE([gl_HEADER_ERRNO_H], [ AC_REQUIRE([AC_PROG_CC]) + + dnl Persuade AIX 7.3 errno.h to make EEXIST != ENOTEMPTY. + AC_DEFINE([_LINUX_SOURCE_COMPAT], [1], + [Define so that AIX headers are more compatible with GNU/Linux.]) + AC_CACHE_CHECK([for complete errno.h], [gl_cv_header_errno_h_complete], [ AC_EGREP_CPP([booboo],[ #include <errno.h> diff --git a/m4/malloc.m4 b/m4/malloc.m4 index 41a46937ea..a410a5c24f 100644 --- a/m4/malloc.m4 +++ b/m4/malloc.m4 @@ -1,5 +1,5 @@ # malloc.m4 -# serial 31 +# serial 32 dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -45,6 +45,11 @@ AC_DEFUN([gl_FUNC_MALLOC_GNU], [ AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) + + dnl This helps if !(__VEC__ || __AIXVEC), and shouldn't hurt otherwise. + AC_DEFINE([_LINUX_SOURCE_COMPAT], [1], + [Define so that AIX headers are more compatible with GNU/Linux.]) + REPLACE_MALLOC_FOR_MALLOC_GNU="$REPLACE_MALLOC_FOR_MALLOC_POSIX" if test $REPLACE_MALLOC_FOR_MALLOC_GNU = 0; then _AC_FUNC_MALLOC_IF([], [REPLACE_MALLOC_FOR_MALLOC_GNU=1]) diff --git a/m4/passfd.m4 b/m4/passfd.m4 index 67e9c2fed0..fe7ad86fd2 100644 --- a/m4/passfd.m4 +++ b/m4/passfd.m4 @@ -1,5 +1,5 @@ # passfd.m4 -# serial 9 +# serial 10 dnl Copyright (C) 2011-2024 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,7 +13,7 @@ AC_DEFUN([gl_PASSFD], dnl Persuade AIX 5.2 <sys/socket.h> to declare CMSG_SPACE, CMSG_LEN. dnl CMSG_FIRSTHDR is POSIX 2008, but CMSG_SPACE is only in RFC 3542. AC_DEFINE([_LINUX_SOURCE_COMPAT], [1], - [Define in order to get some macros on AIX systems.]) + [Define so that AIX headers are more compatible with GNU/Linux.]) dnl Passfd prefers the POSIX use of msg.msg_control if the CMSG_* macros dnl are present, but can fall back to BSD 4.3 style of msg.msg_accrights. diff --git a/m4/realloc.m4 b/m4/realloc.m4 index eb90d5885c..13bb28ce9d 100644 --- a/m4/realloc.m4 +++ b/m4/realloc.m4 @@ -1,5 +1,5 @@ # realloc.m4 -# serial 29 +# serial 30 dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -45,6 +45,11 @@ AC_DEFUN([gl_FUNC_REALLOC_GNU], [ AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) AC_REQUIRE([gl_FUNC_REALLOC_POSIX]) + + dnl This helps if !(__VEC__ || __AIXVEC), and shouldn't hurt otherwise. + AC_DEFINE([_LINUX_SOURCE_COMPAT], [1], + [Define so that AIX headers are more compatible with GNU/Linux.]) + if test $REPLACE_REALLOC_FOR_REALLOC_GNU = 0; then _AC_FUNC_REALLOC_IF([], [REPLACE_REALLOC_FOR_REALLOC_GNU=1]) fi diff --git a/m4/scandir.m4 b/m4/scandir.m4 index f981e1f839..192ac5f154 100644 --- a/m4/scandir.m4 +++ b/m4/scandir.m4 @@ -1,5 +1,5 @@ # scandir.m4 -# serial 2 +# serial 3 dnl Copyright (C) 2009-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -12,6 +12,9 @@ AC_DEFUN([gl_FUNC_SCANDIR], dnl Persuade glibc and Solaris <dirent.h> to declare scandir(). AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + AC_DEFINE([_LINUX_SOURCE_COMPAT], [1], + [Define so that AIX headers are more compatible with GNU/Linux.]) + AC_CHECK_FUNCS([scandir]) if test $ac_cv_func_scandir = no; then HAVE_SCANDIR=0 diff --git a/m4/strerror_r.m4 b/m4/strerror_r.m4 index a83136c686..eae9f1c419 100644 --- a/m4/strerror_r.m4 +++ b/m4/strerror_r.m4 @@ -1,5 +1,5 @@ # strerror_r.m4 -# serial 26 +# serial 27 dnl Copyright (C) 2002, 2007-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -10,6 +10,13 @@ AC_DEFUN([gl_FUNC_STRERROR_R], AC_REQUIRE([gl_STRING_H_DEFAULTS]) AC_REQUIRE([gl_FUNC_STRERROR_R_WORKS]) + dnl On AIX, ask for the GNU/Linux API. Other modules might ask for + dnl that API for other reasons, so we will will need override it because + dnl we cannot easily ask AIX for the GNU/Linux API for everything + dnl but strerror_r. + AC_DEFINE([_LINUX_SOURCE_COMPAT], [1], + [Define so that AIX headers are more compatible with GNU/Linux.]) + dnl Some systems don't declare strerror_r() if _THREAD_SAFE and _REENTRANT dnl are not defined. AC_CHECK_DECLS_ONCE([strerror_r]) diff --git a/modules/errno-tests b/modules/errno-tests index 71e732ce3e..f77aa5ae6b 100644 --- a/modules/errno-tests +++ b/modules/errno-tests @@ -2,6 +2,8 @@ Files: tests/test-errno.c Depends-on: +assert-h +c99 errno-c++-tests configure.ac: @@ -9,4 +11,3 @@ configure.ac: Makefile.am: TESTS += test-errno check_PROGRAMS += test-errno - diff --git a/tests/test-errno.c b/tests/test-errno.c index 99600add83..7403ee1432 100644 --- a/tests/test-errno.c +++ b/tests/test-errno.c @@ -20,90 +20,92 @@ #include <errno.h> -/* Verify that the POSIX mandated errno values exist and can be used as - initializers outside of a function. - The variable names happen to match the Linux/x86 error numbers. */ -int e1 = EPERM; -int e2 = ENOENT; -int e3 = ESRCH; -int e4 = EINTR; -int e5 = EIO; -int e6 = ENXIO; -int e7 = E2BIG; -int e8 = ENOEXEC; -int e9 = EBADF; -int e10 = ECHILD; -int e11 = EAGAIN; -int e11a = EWOULDBLOCK; -int e12 = ENOMEM; -int e13 = EACCES; -int e14 = EFAULT; -int e16 = EBUSY; -int e17 = EEXIST; -int e18 = EXDEV; -int e19 = ENODEV; -int e20 = ENOTDIR; -int e21 = EISDIR; -int e22 = EINVAL; -int e23 = ENFILE; -int e24 = EMFILE; -int e25 = ENOTTY; -int e26 = ETXTBSY; -int e27 = EFBIG; -int e28 = ENOSPC; -int e29 = ESPIPE; -int e30 = EROFS; -int e31 = EMLINK; -int e32 = EPIPE; -int e33 = EDOM; -int e34 = ERANGE; -int e35 = EDEADLK; -int e36 = ENAMETOOLONG; -int e37 = ENOLCK; -int e38 = ENOSYS; -int e39 = ENOTEMPTY; -int e40 = ELOOP; -int e42 = ENOMSG; -int e43 = EIDRM; -int e67 = ENOLINK; -int e71 = EPROTO; -int e72 = EMULTIHOP; -int e74 = EBADMSG; -int e75 = EOVERFLOW; -int e84 = EILSEQ; -int e88 = ENOTSOCK; -int e89 = EDESTADDRREQ; -int e90 = EMSGSIZE; -int e91 = EPROTOTYPE; -int e92 = ENOPROTOOPT; -int e93 = EPROTONOSUPPORT; -int e95 = EOPNOTSUPP; -int e95a = ENOTSUP; -int e97 = EAFNOSUPPORT; -int e98 = EADDRINUSE; -int e99 = EADDRNOTAVAIL; -int e100 = ENETDOWN; -int e101 = ENETUNREACH; -int e102 = ENETRESET; -int e103 = ECONNABORTED; -int e104 = ECONNRESET; -int e105 = ENOBUFS; -int e106 = EISCONN; -int e107 = ENOTCONN; -int e110 = ETIMEDOUT; -int e111 = ECONNREFUSED; -int e113 = EHOSTUNREACH; -int e114 = EALREADY; -int e115 = EINPROGRESS; -int e116 = ESTALE; -int e122 = EDQUOT; -int e125 = ECANCELED; -int e130 = EOWNERDEAD; -int e131 = ENOTRECOVERABLE; +/* Check all POSIX-defined errno values, using M (v) to check value v. */ +#define CHECK_POSIX_ERRNOS(m) \ + m (E2BIG) \ + m (EACCES) \ + m (EADDRINUSE) \ + m (EADDRNOTAVAIL) \ + m (EAFNOSUPPORT) \ + m (EAGAIN) \ + m (EALREADY) \ + m (EBADF) \ + m (EBADMSG) \ + m (EBUSY) \ + m (ECANCELED) \ + m (ECHILD) \ + m (ECONNABORTED) \ + m (ECONNREFUSED) \ + m (ECONNRESET) \ + m (EDEADLK) \ + m (EDESTADDRREQ) \ + m (EDOM) \ + m (EDQUOT) \ + m (EEXIST) \ + m (EFAULT) \ + m (EFBIG) \ + m (EHOSTUNREACH) \ + m (EIDRM) \ + m (EILSEQ) \ + m (EINPROGRESS) \ + m (EINTR) \ + m (EINVAL) \ + m (EIO) \ + m (EISCONN) \ + m (EISDIR) \ + m (ELOOP) \ + m (EMFILE) \ + m (EMLINK) \ + m (EMSGSIZE) \ + m (EMULTIHOP) \ + m (ENAMETOOLONG) \ + m (ENETDOWN) \ + m (ENETRESET) \ + m (ENETUNREACH) \ + m (ENFILE) \ + m (ENOBUFS) \ + m (ENODEV) \ + m (ENOENT) \ + m (ENOEXEC) \ + m (ENOLCK) \ + m (ENOLINK) \ + m (ENOMEM) \ + m (ENOMSG) \ + m (ENOPROTOOPT) \ + m (ENOSPC) \ + m (ENOSYS) \ + m (ENOTCONN) \ + m (ENOTDIR) \ + m (ENOTEMPTY) \ + m (ENOTRECOVERABLE) \ + m (ENOTSOCK) \ + m (ENOTSUP) \ + m (ENOTTY) \ + m (ENXIO) \ + m (EOPNOTSUPP) \ + m (EOVERFLOW) \ + m (EOWNERDEAD) \ + m (EPERM) \ + m (EPIPE) \ + m (EPROTO) \ + m (EPROTONOSUPPORT) \ + m (EPROTOTYPE) \ + m (ERANGE) \ + m (EROFS) \ + m (ESOCKTNOSUPPORT) \ + m (ESPIPE) \ + m (ESRCH) \ + m (ESTALE) \ + m (ETIMEDOUT) \ + m (ETXTBSY) \ + m (EWOULDBLOCK) \ + m (EXDEV) \ + /* end of CHECK_POSIX_ERRNOS */ -/* Don't verify that these errno values are all different, except for possibly - EWOULDBLOCK == EAGAIN. Even Linux/x86 does not pass this check: it has - ENOTSUP == EOPNOTSUPP. */ +/* Verify that the POSIX mandated errno values can be used as integer + constant expressions and are all positive. */ +#define POSITIVE_INTEGER_CONSTANT_EXPRESSION(e) static_assert (0 < (e) << 0); +CHECK_POSIX_ERRNOS (POSITIVE_INTEGER_CONSTANT_EXPRESSION) int main () @@ -111,9 +113,18 @@ main () /* Verify that errno can be assigned. */ errno = EOVERFLOW; - /* snprintf() callers want to distinguish EINVAL and EOVERFLOW. */ - if (errno == EINVAL) - return 1; - - return 0; + /* Check that errno values all differ, except possibly for + EWOULDBLOCK == EAGAIN and ENOTSUP == EOPNOTSUPP. */ + #define INDEXED_BY_ERRNO(e) [e] = 1, + #define ERRNO_COUNT(e) 0, + static char const + indexed_by_errno[] = { CHECK_POSIX_ERRNOS (INDEXED_BY_ERRNO) }, + errno_count[] = { CHECK_POSIX_ERRNOS (ERRNO_COUNT) }; + int distinct_errnos = 0; + for (int i = 0; i < sizeof indexed_by_errno; i++) + distinct_errnos += indexed_by_errno[i]; + return ((sizeof errno_count + - (EWOULDBLOCK == EAGAIN) + - (ENOTSUP == EOPNOTSUPP)) + != distinct_errnos); } -- 2.43.0