From deee99a01db325f8119cd38aa7f09cc71134c3e5 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sun, 27 Dec 2020 12:40:05 +0100 Subject: [PATCH] Fix build for systems that don't provide POSIX.1-2001 by default We require POSIX.1-2001. Some systems provide it only with feature test macro _POSIX_C_SOURCE defined to 200112L. Since we don't define it, the build fails there. Observed on Solaris 10. We actually require the XSI extension. The GNU C Library provides it by default. With _POSIX_C_SOURCE 200112L, however, you have to define feature test macro _XOPEN_SOURCE to get it. But then _POSIX_C_SOURCE is redundant. Make configure put #define _XOPEN_SOURCE 600 into config.h. Drop the two existing #define _XOPEN_SOURCE 500 in .c files. Now Solaris cc refuses to play ball unless switched to C99. Replace AC_PROG_CC by AC_PROG_CC_STDC to mollify it. Unfortunately, use of _XOPEN_SOURCE exposes bugs in AIX libc and old versions of GNU libc: * AIX defines struct in6_addr's member s6_addr as a macro expanding into the actual member. Without _ALL_SOURCE (the default), the expansion is wrong and doesn't compile. Observed with AIX V7.2. * GNU lib's IN6_IS_ADDR_V4MAPPED() is unusable without _DEFAULT_SOURCE (default) or _GNU_SOURCE. Observed with Debian 8. Tracked at , fixed in version 2.25. Affects just sockaddr_ntop()'s special case from commit 372cdb136 "Use IPv4 format for IPv4-mapped addresses", v4.3.31. Disable the special case and use IPv6 format on such systems. This is a very minor usability regression. Could be avoided, I guess, but it's not worth the trouble. Signed-off-by: Markus Armbruster --- configure.ac | 9 +++++++-- m4/my_working_in6_is_addr_v4mapped.m4 | 20 ++++++++++++++++++++ src/client/configure.ac | 3 +++ src/lib/common/rdsched.c | 3 --- src/lib/empthread/pthread.c | 3 --- src/lib/global/constants.c | 8 ++++++-- src/lib/player/accept.c | 4 +++- 7 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 m4/my_working_in6_is_addr_v4mapped.m4 diff --git a/configure.ac b/configure.ac index 4113bc78..b37129a5 100644 --- a/configure.ac +++ b/configure.ac @@ -46,15 +46,19 @@ AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([config.h]) - ### Checks for programs AC_PROG_AWK AC_PROG_INSTALL AC_PROG_RANLIB -AC_PROG_CC + +AC_PROG_CC_STDC AM_PROG_CC_C_O # Private automake macro, tsk, tsk, tsk... _AM_DEPENDENCIES(CC) +AC_DEFINE([_XOPEN_SOURCE], [600], + [Request POSIX-1.2001 with XSI Extension]) +# Note: this is after AC_PROG_CC_STDC, because Solaris cc fails with +# _XOPEN_SOURCE unless switched to C99, which breaks AC_PROG_CC_STDC. AC_ARG_VAR(NROFF, [nroff command]) AC_CHECK_PROG(NROFF, groff, [GROFF_NO_SGR= groff -Tascii -U], nroff) @@ -168,6 +172,7 @@ main(int argc, char *argv[]) ### Checks for library functions AC_CHECK_FUNCS(getaddrinfo) +MY_WORKING_IN6_IS_ADDR_V4MAPPED MY_FUNC_MAKECONTEXT diff --git a/m4/my_working_in6_is_addr_v4mapped.m4 b/m4/my_working_in6_is_addr_v4mapped.m4 new file mode 100644 index 00000000..2c476826 --- /dev/null +++ b/m4/my_working_in6_is_addr_v4mapped.m4 @@ -0,0 +1,20 @@ +AC_DEFUN([MY_WORKING_IN6_IS_ADDR_V4MAPPED], [ + AC_CACHE_CHECK([whether IN6_IS_ADDR_V4MAPPED works], + my_cv_func_in6_is_addr_v4mapped, [ + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[#include +int foo(struct sockaddr_in6 *sap6) +{ + return IN6_IS_ADDR_V4MAPPED(&sap6->sin6_addr); +}]])], + [my_cv_func_in6_is_addr_v4mapped=yes], + [my_cv_func_in6_is_addr_v4mapped=no])]) + AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_addr.s6_addr], + [my_member_sockaddr_in6_sin6_addr_s6_addr=yes], + [my_member_sockaddr_in6_sin6_addr_s6_addr=no], + [[#include ]]) + if test "x$my_cv_func_in6_is_addr_v4mapped$my_member_sockaddr_in6_sin6_addr_s6_addr" = xyesyes; then + AC_DEFINE([HAVE_WORKING_IN6_IS_ADDR_V4MAPPED], [1], + [Define if you have a working IN6_IS_ADDR_V4MAPPED()]) + fi +]) diff --git a/src/client/configure.ac b/src/client/configure.ac index 00aac39e..76268544 100644 --- a/src/client/configure.ac +++ b/src/client/configure.ac @@ -44,6 +44,9 @@ AC_INIT([Wolfpack Empire Client], AC_CONFIG_SRCDIR([empire.6]) AC_CONFIG_HEADERS([config.h]) +AC_DEFINE([_XOPEN_SOURCE], [600], + [Request POSIX-1.2001 with XSI Extension]) + ### Checks for programs. AC_PROG_CC diff --git a/src/lib/common/rdsched.c b/src/lib/common/rdsched.c index a98ec0a4..05b518c2 100644 --- a/src/lib/common/rdsched.c +++ b/src/lib/common/rdsched.c @@ -30,9 +30,6 @@ * Markus Armbruster, 2007-2011 */ -/* Required for strptime() */ -#define _XOPEN_SOURCE 500 - #include #include diff --git a/src/lib/empthread/pthread.c b/src/lib/empthread/pthread.c index 2d8b5092..3e02132d 100644 --- a/src/lib/empthread/pthread.c +++ b/src/lib/empthread/pthread.c @@ -33,9 +33,6 @@ * Ron Koenderink, 2007-2009 */ -/* Required for PTHREAD_STACK_MIN on some systems, e.g. Solaris: */ -#define _XOPEN_SOURCE 500 - #include #include diff --git a/src/lib/global/constants.c b/src/lib/global/constants.c index 252a8a96..1e09e586 100644 --- a/src/lib/global/constants.c +++ b/src/lib/global/constants.c @@ -29,7 +29,7 @@ * Known contributors to this file: * Ken Stevens, 1995 * Steve McClure, 1996 - * Markus Armbruster, 2004-2014 + * Markus Armbruster, 2004-2020 */ #include @@ -41,7 +41,11 @@ char *privname = "Deity forgot to edit econfig"; /* E-mail of the deity */ char *privlog = "careless@invalid"; /* Divine hosts and networks */ -char *privip = "127.0.0.1 ::1"; +char *privip = "127.0.0.1 ::1" +#ifndef HAVE_WORKING_IN6_IS_ADDR_V4MAPPED + " ::ffff:127.0.0.1" /* See sockaddr_ntop() */ +#endif + ; char *post_crash_dump_hook = ""; diff --git a/src/lib/player/accept.c b/src/lib/player/accept.c index a631f79b..0ec2a93f 100644 --- a/src/lib/player/accept.c +++ b/src/lib/player/accept.c @@ -28,7 +28,7 @@ * * Known contributors to this file: * Dave Pare, 1994 - * Markus Armbruster, 2005-2014 + * Markus Armbruster, 2005-2020 */ #include @@ -228,10 +228,12 @@ sockaddr_ntop(struct sockaddr *sap, char *buf, size_t bufsz) else { sap6 = (struct sockaddr_in6 *)sap; addr = &sap6->sin6_addr; +#ifdef HAVE_WORKING_IN6_IS_ADDR_V4MAPPED if (IN6_IS_ADDR_V4MAPPED(&sap6->sin6_addr)) { af = AF_INET; addr = sap6->sin6_addr.s6_addr + 12; } +#endif } return inet_ntop(af, addr, buf, bufsz); #else