GNetworkMonitorNetlink: make the netlink socket cloexec
authorDan Winship <danw@gnome.org>
Tue, 22 Jan 2013 21:39:49 +0000 (16:39 -0500)
committerDan Winship <danw@gnome.org>
Wed, 23 Jan 2013 13:48:32 +0000 (08:48 -0500)
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
gio/gnetworkmonitornetlink.c
gio/gsocket.c

index 5c286f3..1a299c9 100644 (file)
@@ -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__ */
index 3f67654..f909ca9 100644 (file)
@@ -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;
index 9968ead..5c524a4 100644 (file)
@@ -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