[glib] struct ip_mreq_source definition is broken on Android NDK <= r16



commit 7efd76dd6796f886134436e04fb149132b18b989
Author: Xavier Claessens <xavier claessens collabora com>
Date:   Mon Apr 23 11:47:17 2018 -0400

    struct ip_mreq_source definition is broken on Android NDK <= r16
    
    This fix the build on Android r16 and older, see:
    https://issuetracker.google.com/issues/36987220
    
    https://bugzilla.gnome.org/show_bug.cgi?id=740791

 config.h.meson  |  3 +++
 configure.ac    | 15 +++++++++++++++
 gio/gsocket.c   | 16 +++++++++++++---
 gio/meson.build | 10 ++++++++++
 4 files changed, 41 insertions(+), 3 deletions(-)
---
diff --git a/config.h.meson b/config.h.meson
index 2bfe3f6b2..84cafa261 100644
--- a/config.h.meson
+++ b/config.h.meson
@@ -15,6 +15,9 @@
 /* poll doesn't work on devices */
 #mesondefine BROKEN_POLL
 
+/* struct ip_mreq_source definition is broken on Android NDK <= r16 */
+#mesondefine BROKEN_IP_MREQ_SOURCE_STRUCT
+
 /* Whether we're building a DLL and hence need symbols exported for a DLL */
 #mesondefine DLL_EXPORT
 
diff --git a/configure.ac b/configure.ac
index 44c5ada59..8dac7cbaf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -961,6 +961,21 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
         AC_MSG_RESULT(no)
 ])
 
+AC_MSG_CHECKING([if ip_mreq_source.imr_interface has s_addr member])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+    [[
+        #include <netinet/in.h>
+    ]],
+    [[
+        struct ip_mreq_source mc_req_src;
+        mc_req_src.imr_interface.s_addr = 0;
+    ]])], [
+        AC_MSG_RESULT(yes)
+    ], [
+        AC_MSG_RESULT(no)
+        AC_DEFINE(BROKEN_IP_MREQ_SOURCE_STRUCT, 1, [struct ip_mreq_source definition is broken on Android 
NDK <= r16])
+])
+
 AS_IF([test $glib_native_win32 = yes], [
   # <wspiapi.h> in the Windows SDK and in mingw-w64 has wrappers for
   # inline workarounds for getaddrinfo, getnameinfo and freeaddrinfo if
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 06042d8a8..b4a941eb1 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -2380,6 +2380,13 @@ g_socket_multicast_group_operation_ssm (GSocket       *socket,
     case G_SOCKET_FAMILY_IPV4:
       {
 #ifdef IP_ADD_SOURCE_MEMBERSHIP
+
+#ifdef BROKEN_IP_MREQ_SOURCE_STRUCT
+#define S_ADDR_FIELD(src) src.imr_interface
+#else
+#define S_ADDR_FIELD(src) src.imr_interface.s_addr
+#endif
+
         gint optname;
         struct ip_mreq_source mc_req_src;
 
@@ -2397,7 +2404,7 @@ g_socket_multicast_group_operation_ssm (GSocket       *socket,
         memset (&mc_req_src, 0, sizeof (mc_req_src));
 
         /* By default use the default IPv4 multicast interface. */
-        mc_req_src.imr_interface.s_addr = g_htonl (INADDR_ANY);
+        S_ADDR_FIELD(mc_req_src) = g_htonl (INADDR_ANY);
 
         if (iface)
           {
@@ -2412,7 +2419,7 @@ g_socket_multicast_group_operation_ssm (GSocket       *socket,
                 return FALSE;
               }
             /* (0.0.0.iface_index) only works on Windows. */
-            mc_req_src.imr_interface.s_addr = g_htonl (iface_index);
+            S_ADDR_FIELD(mc_req_src) = g_htonl (iface_index);
 #elif defined (HAVE_SIOCGIFADDR)
             int ret;
             struct ifreq ifr;
@@ -2442,7 +2449,7 @@ g_socket_multicast_group_operation_ssm (GSocket       *socket,
               }
 
             iface_addr = (struct sockaddr_in *) &ifr.ifr_addr;
-            mc_req_src.imr_interface.s_addr = iface_addr->sin_addr.s_addr;
+            S_ADDR_FIELD(mc_req_src) = iface_addr->sin_addr.s_addr;
 #endif  /* defined(G_OS_WIN32) && defined (HAVE_IF_NAMETOINDEX) */
           }
         memcpy (&mc_req_src.imr_multiaddr, g_inet_address_to_bytes (group),
@@ -2455,6 +2462,9 @@ g_socket_multicast_group_operation_ssm (GSocket       *socket,
             join_group ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP;
         result = setsockopt (socket->priv->fd, IPPROTO_IP, optname,
                              &mc_req_src, sizeof (mc_req_src));
+
+#undef S_ADDR_FIELD
+
 #else
         g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
             join_group ?
diff --git a/gio/meson.build b/gio/meson.build
index 6028f3b7f..5a4a8c53e 100644
--- a/gio/meson.build
+++ b/gio/meson.build
@@ -152,6 +152,16 @@ if host_system != 'windows'
     glib_conf.set('HAVE_SIOCGIFADDR', '/**/')
   endif
 
+  if not cc.compiles('''#include <netinet/in.h>
+                        int main(int argc, char ** argv) {
+                          struct ip_mreq_source mc_req_src;
+                          mc_req_src.imr_interface.s_addr = 0;
+                          return 0;
+                        }''',
+                        name : 'ip_mreq_source.imr_interface has s_addr member')
+    glib_conf.set('BROKEN_IP_MREQ_SOURCE_STRUCT', 1)
+  endif
+
 endif
 
 network_args_string = ''


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]