Просмотр исходного кода

Implement Dns.GetHostEntry(string.Empty) on Mac OS.

* configure.in: Add check for getifaddrs().

* socket-io.c: Implement get_local_ips() using getifaddrs()
  if SIOCGIFCONF is not available.

* DnsTest.cs: Add GetHostEmpty_StringEmpty().

* UdpClientTest.cs(): Enable Available(), BeginReceive() and BeginSend()
  on the Mac.
Martin Baulig 13 лет назад
Родитель
Сommit
504e2341ba

+ 21 - 1
configure.in

@@ -1720,7 +1720,27 @@ if test x$target_win32 = xno; then
 			AC_DEFINE(HAVE_SOCKADDR_IN6_SIN_LEN, 1, [sockaddr_in6 has sin6_len])
 		], [
 			AC_MSG_RESULT(no)
-		])	
+		])
+	dnl **********************************
+	dnl *** Check for getifaddrs       ***
+	dnl **********************************
+	AC_MSG_CHECKING(for getifaddrs)
+		AC_TRY_LINK([
+		#include <stdio.h>
+		#include <sys/types.h>
+		#include <sys/socket.h>
+		#include <ifaddrs.h>
+	], [
+		getifaddrs(NULL);
+	], [
+		# Yes, we have it...
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_GETIFADDRS, 1, [Have getifaddrs])
+	], [
+		AC_MSG_RESULT(no)
+	])
+
+			
 	dnl **********************************
 	dnl *** Checks for MonoPosixHelper ***
 	dnl **********************************

+ 0 - 3
mcs/class/System/Test/System.Net.Sockets/UdpClientTest.cs

@@ -961,7 +961,6 @@ namespace MonoTests.System.Net.Sockets {
 		}
 		
 		[Test]
-		[Category ("NotOnMac")]
 		public void BeginSend ()
 		{
 			UdpClient client = new UdpClient ();
@@ -1016,7 +1015,6 @@ namespace MonoTests.System.Net.Sockets {
 		}
 		
 		[Test]
-		[Category ("NotOnMac")]
 		public void BeginReceive ()
 		{
 			UdpClient client = new UdpClient (1237);
@@ -1042,7 +1040,6 @@ namespace MonoTests.System.Net.Sockets {
 		}
 		
 		[Test]
-		[Category ("NotOnMac")]
 		public void Available ()
 		{
 			UdpClient client = new UdpClient (1238);

+ 6 - 0
mcs/class/System/Test/System.Net/DnsTest.cs

@@ -501,6 +501,12 @@ namespace MonoTests.System.Net
 			Assert.IsTrue (h.AddressList.Length > 0, "AddressList.Length");
 		}
 
+		[Test]
+		public void GetHostEntry_StringEmpty ()
+		{
+			Dns.GetHostEntry (string.Empty);
+		}
+
 		/* This isn't used anymore, but could be useful for debugging
 		static void printIPHostEntry(IPHostEntry h)
 		{

+ 76 - 0
mono/metadata/socket-io.c

@@ -74,6 +74,11 @@
 #include <sys/un.h>
 #endif
 
+#ifdef HAVE_GETIFADDRS
+// <net/if.h> must be included before <ifaddrs.h>
+#include <ifaddrs.h>
+#endif
+
 #include "mono/io-layer/socket-wrappers.h"
 
 #if defined(HOST_WIN32)
@@ -2425,6 +2430,77 @@ get_local_ips (int family, int *nips)
 	g_free (ifc.ifc_buf);
 	return result;
 }
+#elif defined(HAVE_GETIFADDRS)
+static gboolean
+is_loopback (int family, void *ad)
+{
+	char *ptr = (char *) ad;
+
+	if (family == AF_INET) {
+		return (ptr [0] == 127);
+	}
+#ifdef AF_INET6
+	else {
+		return (IN6_IS_ADDR_LOOPBACK ((struct in6_addr *) ptr));
+	}
+#endif
+	return FALSE;
+}
+
+static void *
+get_local_ips (int family, int *nips)
+{
+	struct ifaddrs *ifap = NULL, *ptr;
+	int addr_size, offset, count, i;
+	char *result, *tmp_ptr;
+
+	*nips = 0;
+	if (family == AF_INET) {
+		addr_size = sizeof (struct in_addr);
+		offset = G_STRUCT_OFFSET (struct sockaddr_in, sin_addr);
+#ifdef AF_INET6
+	} else if (family == AF_INET6) {
+		addr_size = sizeof (struct in6_addr);
+		offset = G_STRUCT_OFFSET (struct sockaddr_in6, sin6_addr);
+#endif
+	} else {
+		return NULL;
+	}
+	
+	if (getifaddrs (&ifap)) {
+		fprintf(stderr, "get_local_ips() error: %s\n", strerror (errno));
+		return NULL;
+	}
+	
+	count = 0;
+	for (ptr = ifap; ptr; ptr = ptr->ifa_next) {
+		if (!ptr->ifa_addr)
+			continue;
+		if (ptr->ifa_addr->sa_family != family)
+			continue;
+		if (is_loopback (family, ((char *) ptr->ifa_addr) + offset))
+			continue;
+		count++;
+	}
+		
+	result = g_malloc (addr_size * count);
+	tmp_ptr = result;
+	for (i = 0, ptr = ifap; ptr; ptr = ptr->ifa_next) {
+		if (!ptr->ifa_addr)
+			continue;
+		if (ptr->ifa_addr->sa_family != family)
+			continue;
+		if (is_loopback (family, ((char *) ptr->ifa_addr) + offset))
+			continue;
+			
+		memcpy (tmp_ptr, ((char *) ptr->ifa_addr) + offset, addr_size);
+		tmp_ptr += addr_size;
+	}
+	
+	freeifaddrs (ifap);
+	*nips = count;
+	return result;
+}
 #else
 static void *
 get_local_ips (int family, int *nips)