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 Paul Eggert <eggert@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 <bruno@clisp.org>
float: Update to mostly guarantee ISO C 23 compliance.
@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
@itemize
@item
@code{malloc (0)} returns @code{NULL} on success on some platforms:
-AIX 7.2.
+AIX 7.3.
@end itemize
@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}
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);
@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:
/* 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 */
# 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,
[
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])
# 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,
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>
# 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,
[
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])
# 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,
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.
# 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,
[
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
# 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,
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
# 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,
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])
tests/test-errno.c
Depends-on:
+assert-h
+c99
errno-c++-tests
configure.ac:
Makefile.am:
TESTS += test-errno
check_PROGRAMS += test-errno
-
#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 ()
/* 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);
}