[gnio] Always set close-on-exec on socket fds we create



commit 50189e8f049cf50cbaae17f23f45c62ffb24fad2
Author: Alexander Larsson <alexl redhat com>
Date:   Wed May 6 13:59:58 2009 +0200

    Always set close-on-exec on socket fds we create
    
    This is safer for all normal use, if you need to do something weird
    you need to manually disable this. We also use the new SOCK_CLOEXEC
    flag to do this atomically if possible.
---
 gio/gsocket.c |   49 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/gio/gsocket.c b/gio/gsocket.c
index 88940d8..16f74f8 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -394,6 +394,9 @@ g_socket_create_socket (GSocketFamily   family,
       protocol = protoent->p_proto;
     }
 
+#ifdef SOCK_CLOEXEC
+  native_type |= SOCK_CLOEXEC;
+#endif
   fd = socket (family, native_type, protocol);
 
   if (fd < 0)
@@ -404,6 +407,23 @@ g_socket_create_socket (GSocketFamily   family,
                    _("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;
 }
 
@@ -987,8 +1007,6 @@ g_socket_accept (GSocket       *socket,
 
   win32_unset_event_mask (socket, FD_ACCEPT);
 
-  new_socket = g_socket_new_from_fd (ret);
-
 #ifdef G_OS_WIN32
   {
     gulong arg;
@@ -1001,11 +1019,32 @@ g_socket_accept (GSocket       *socket,
        sockets are blocking, disable blocking to get the same behaviour
        as on unix. */
     arg = FALSE;
-    if (ioctlsocket (new_socket->priv->fd, FIONBIO, &arg) == SOCKET_ERROR)
+    if (ioctlsocket (ret, FIONBIO, &arg) == SOCKET_ERROR)
       g_warning ("Unable to set newly allocated socket to blocking mode");
-    new_socket->priv->blocking = TRUE;
-    new_socket->priv->blocking_mode_unknown = FALSE;
   }
+#else
+  {
+    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 (ret, F_GETFD, 0);
+    if (flags != -1 &&
+	(flags & FD_CLOEXEC) == 0)
+      {
+	flags |= FD_CLOEXEC;
+	fcntl (ret, F_SETFD, flags);
+      }
+  }
+#endif
+
+  new_socket = g_socket_new_from_fd (ret);
+
+#ifdef G_OS_WIN32
+  /* We set blocking above, and new_from_fd can't read this on win32 */
+  new_socket->priv->blocking = TRUE;
+  new_socket->priv->blocking_mode_unknown = FALSE;
 #endif
 
   return new_socket;



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