[glib] GNetworkMonitorNetlink: make the netlink socket cloexec



commit 5932e16acda9434cd4e9d76cf6faba4b8217357f
Author: Dan Winship <danw gnome org>
Date:   Tue Jan 22 16:39:49 2013 -0500

    GNetworkMonitorNetlink: make the netlink socket cloexec
    
    Use the same code GSocket does, to try SOCK_CLOEXEC first, and then
    fall back to FD_CLOEXEC if it fails. (And fix that code to not call
    fcntl if SOCK_CLOEXEC worked.)
    
    https://bugzilla.gnome.org/show_bug.cgi?id=692332

 gio/gnetworkingprivate.h     |    5 ++
 gio/gnetworkmonitornetlink.c |    2 +-
 gio/gsocket.c                |   86 +++++++++++++++++++++++++-----------------
 3 files changed, 57 insertions(+), 36 deletions(-)
---
diff --git a/gio/gnetworkingprivate.h b/gio/gnetworkingprivate.h
index 5c286f3..1a299c9 100644
--- a/gio/gnetworkingprivate.h
+++ b/gio/gnetworkingprivate.h
@@ -34,6 +34,11 @@ gchar *  _g_uri_from_authority             (const gchar      *protocol,
 					    guint             port,
 					    const gchar      *userinfo);
 
+gint g_socket (gint     domain,
+               gint     type,
+               gint     protocol,
+               GError **error);
+
 G_END_DECLS
 
 #endif /* __G_NETWORKINGPRIVATE_H__ */
diff --git a/gio/gnetworkmonitornetlink.c b/gio/gnetworkmonitornetlink.c
index 3f67654..f909ca9 100644
--- a/gio/gnetworkmonitornetlink.c
+++ b/gio/gnetworkmonitornetlink.c
@@ -89,7 +89,7 @@ g_network_monitor_netlink_initable_init (GInitable     *initable,
   /* We create the socket the old-school way because sockaddr_netlink
    * can't be represented as a GSocketAddress
    */
-  sockfd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  sockfd = g_socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE, NULL);
   if (sockfd == -1)
     {
       int errsv = errno;
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 9968ead..5c524a4 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -59,7 +59,7 @@
 #include "gioerror.h"
 #include "gioenums.h"
 #include "gioerror.h"
-#include "gnetworking.h"
+#include "gnetworkingprivate.h"
 #include "gsocketaddress.h"
 #include "gsocketcontrolmessage.h"
 #include "gcredentials.h"
@@ -482,6 +482,55 @@ g_socket_details_from_fd (GSocket *socket)
 	       socket_strerror (errsv));
 }
 
+/* Wrapper around socket() that is shared with gnetworkmonitornetlink.c */
+gint
+g_socket (gint     domain,
+          gint     type,
+          gint     protocol,
+          GError **error)
+{
+  int fd;
+
+#ifdef SOCK_CLOEXEC
+  fd = socket (domain, type | SOCK_CLOEXEC, protocol);
+  if (fd != -1)
+    return fd;
+
+  /* It's possible that libc has SOCK_CLOEXEC but the kernel does not */
+  if (fd < 0 && errno == EINVAL)
+#endif
+    fd = socket (domain, type, protocol);
+
+  if (fd < 0)
+    {
+      int errsv = get_socket_errno ();
+
+      g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv),
+		   _("Unable to create socket: %s"), socket_strerror (errsv));
+      errno = errsv;
+      return -1;
+    }
+
+#ifndef G_OS_WIN32
+  {
+    int flags;
+
+    /* We always want to set close-on-exec to protect users. If you
+       need to so some weird inheritance to exec you can re-enable this
+       using lower level hacks with g_socket_get_fd(). */
+    flags = fcntl (fd, F_GETFD, 0);
+    if (flags != -1 &&
+	(flags & FD_CLOEXEC) == 0)
+      {
+	flags |= FD_CLOEXEC;
+	fcntl (fd, F_SETFD, flags);
+      }
+  }
+#endif
+
+  return fd;
+}
+
 static gint
 g_socket_create_socket (GSocketFamily   family,
 			GSocketType     type,
@@ -489,7 +538,6 @@ g_socket_create_socket (GSocketFamily   family,
 			GError        **error)
 {
   gint native_type;
-  gint fd;
 
   switch (type)
     {
@@ -523,39 +571,7 @@ g_socket_create_socket (GSocketFamily   family,
       return -1;
     }
 
-#ifdef SOCK_CLOEXEC
-  fd = socket (family, native_type | SOCK_CLOEXEC, protocol);
-  /* It's possible that libc has SOCK_CLOEXEC but the kernel does not */
-  if (fd < 0 && errno == EINVAL)
-#endif
-    fd = socket (family, native_type, protocol);
-
-  if (fd < 0)
-    {
-      int errsv = get_socket_errno ();
-
-      g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv),
-		   _("Unable to create socket: %s"), socket_strerror (errsv));
-    }
-
-#ifndef G_OS_WIN32
-  {
-    int flags;
-
-    /* We always want to set close-on-exec to protect users. If you
-       need to so some weird inheritance to exec you can re-enable this
-       using lower level hacks with g_socket_get_fd(). */
-    flags = fcntl (fd, F_GETFD, 0);
-    if (flags != -1 &&
-	(flags & FD_CLOEXEC) == 0)
-      {
-	flags |= FD_CLOEXEC;
-	fcntl (fd, F_SETFD, flags);
-      }
-  }
-#endif
-
-  return fd;
+  return g_socket (family, native_type, protocol, error);
 }
 
 static void



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