Fix build for systems that don't provide POSIX.1-2001 by default
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 27 Dec 2020 11:40:05 +0000 (12:40 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Sun, 17 Jan 2021 20:24:28 +0000 (21:24 +0100)
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 <https://sourceware.org/bugzilla/show_bug.cgi?id=16421>,
  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 <armbru@pond.sub.org>
configure.ac
m4/my_working_in6_is_addr_v4mapped.m4 [new file with mode: 0644]
src/client/configure.ac
src/lib/common/rdsched.c
src/lib/empthread/pthread.c
src/lib/global/constants.c
src/lib/player/accept.c

index 4113bc781d2cbad3c80ba18808f9f23a30274a9d..b37129a58fec6e469f6427acc21b3963db54f57c 100644 (file)
@@ -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 (file)
index 0000000..2c47682
--- /dev/null
@@ -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 <netinet/in.h>
+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 <netinet/in.h>]])
+    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
+])
index 00aac39ec46c0efa034a83a10f4a5a039aeb93c3..76268544322adde27c317a22fb4dc67e6bab886d 100644 (file)
@@ -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
index a98ec0a45a8b1553eeef170836b3360c34b92d78..05b518c2e5ae117e470ef414ba0c933711050e67 100644 (file)
@@ -30,9 +30,6 @@
  *     Markus Armbruster, 2007-2011
  */
 
-/* Required for strptime() */
-#define _XOPEN_SOURCE 500
-
 #include <config.h>
 
 #include <ctype.h>
index 2d8b5092b7a06dc21b944691b00451674107a66a..3e02132d46875ab41cb2b35c1b509cb6f42bdedd 100644 (file)
@@ -33,9 +33,6 @@
  *     Ron Koenderink, 2007-2009
  */
 
-/* Required for PTHREAD_STACK_MIN on some systems, e.g. Solaris: */
-#define _XOPEN_SOURCE 500
-
 #include <config.h>
 
 #include <errno.h>
index 252a8a96cbcc15f5ada9a02600c19e5c8cbf618b..1e09e5864b2d08969635cda5937cf0ab1332d9f7 100644 (file)
@@ -29,7 +29,7 @@
  *  Known contributors to this file:
  *     Ken Stevens, 1995
  *     Steve McClure, 1996
- *     Markus Armbruster, 2004-2014
+ *     Markus Armbruster, 2004-2020
  */
 
 #include <config.h>
@@ -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 = "";
 
index a631f79bd19b45bf6bed2a756be97fbec30c47d8..0ec2a93f0865cc37382b8b6aaa3e4eaee770458f 100644 (file)
@@ -28,7 +28,7 @@
  *
  *  Known contributors to this file:
  *     Dave Pare, 1994
- *     Markus Armbruster, 2005-2014
+ *     Markus Armbruster, 2005-2020
  */
 
 #include <config.h>
@@ -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