[glib] gsocket: fix g_socket_details_from_fd() on Solaris



commit af2a905e5480bc7eb82e7a43ef7fead7b3b90dd7
Author: Dan Winship <danw gnome org>
Date:   Sat Sep 3 19:14:16 2011 -0400

    gsocket: fix g_socket_details_from_fd() on Solaris
    
    On Solaris, getsockname() on an unconnected socket gives an addrlen of
    0 and doesn't set the sockaddr. So use the SO_DOMAIN sockopt to find
    the socket family in that case. (SO_DOMAIN doesn't exist everywhere,
    so we can't use it unconditionally. Also, we have to only use it if
    getsockname() fails, since SO_DOMAIN returns a bogus value for
    accept()ed sockets on both Linux and Solaris...)

 gio/gsocket.c |   30 ++++++++++++++++++++++++++----
 1 files changed, 26 insertions(+), 4 deletions(-)
---
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 2ee0b5c..9d58c41 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -309,7 +309,7 @@ g_socket_details_from_fd (GSocket *socket)
   gint fd;
   guint addrlen;
   guint optlen;
-  int value;
+  int value, family;
   int errsv;
 #ifdef G_OS_WIN32
   /* See bug #611756 */
@@ -370,9 +370,31 @@ g_socket_details_from_fd (GSocket *socket)
       goto err;
     }
 
-  g_assert (G_STRUCT_OFFSET (struct sockaddr, sa_family) +
-	    sizeof address.ss_family <= addrlen);
-  switch (address.ss_family)
+  if (addrlen > 0)
+    {
+      g_assert (G_STRUCT_OFFSET (struct sockaddr, sa_family) +
+		sizeof address.ss_family <= addrlen);
+      family = address.ss_family;
+    }
+  else
+    {
+      /* On Solaris, this happens if the socket is not yet connected.
+       * But we can use SO_DOMAIN as a workaround there.
+       */
+#ifdef SO_DOMAIN
+      optlen = sizeof family;
+      if (getsockopt (fd, SOL_SOCKET, SO_DOMAIN, (void *)&family, &optlen) != 0)
+	{
+	  errsv = get_socket_errno ();
+	  goto err;
+	}
+#else
+      errsv = ENOTSUP;
+      goto err;
+#endif
+    }
+
+  switch (family)
     {
      case G_SOCKET_FAMILY_IPV4:
      case G_SOCKET_FAMILY_IPV6:



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