Fix for close on exec for socket.
authorBrian Aker <brian@tangent.org>
Tue, 5 Jun 2012 22:30:45 +0000 (23:30 +0100)
committerBrian Aker <brian@tangent.org>
Tue, 5 Jun 2012 22:30:45 +0000 (23:30 +0100)
configure.ac
libmemcached/connect.cc
m4/check_sock_cloexec.m4 [new file with mode: 0644]

index e2d368145f33cf4a46068a1b84c665df68df8908..588e1f6123df924f7f98e8f32082a95f32d702a0 100644 (file)
@@ -293,6 +293,9 @@ fi
 
 AC_C_ENDIAN
 
+AX_CHECK_SOCK_CLOEXEC([AC_DEFINE([HAVE_SOCK_CLOEXEC], [1], [Check for SOCK_CLOEXEC.])],
+                       [AC_DEFINE([HAVE_SOCK_CLOEXEC], [0], [Check for SOCK_CLOEXEC.])])
+
 AC_CONFIG_FILES([
   Makefile
   docs/conf.py
index 34e72f76b34231f520b8c170933a9df57f44adf2..8e8092c860cc29c95f8499a050cd365d95e72bc3 100644 (file)
 #include <ctime>
 #include <sys/time.h>
 
+#ifndef SOCK_CLOEXEC 
+#define SOCK_CLOEXEC 0
+#endif
+
 static memcached_return_t connect_poll(memcached_server_st *server)
 {
   struct pollfd fds[1];
@@ -451,13 +455,30 @@ static memcached_return_t network_connect(memcached_server_st *server)
       continue;
     }
 
+    int type= server->address_info_next->ai_socktype;
+    if (HAVE_SOCK_CLOEXEC)
+    {
+      type|= SOCK_CLOEXEC;
+    }
+
     if ((server->fd= socket(server->address_info_next->ai_family,
-                            server->address_info_next->ai_socktype,
+                            type,
                             server->address_info_next->ai_protocol)) < 0)
     {
       return memcached_set_errno(*server, get_socket_errno(), NULL);
     }
 
+    if (HAVE_SOCK_CLOEXEC == 0)
+    {
+#ifdef FD_CLOEXEC
+      int rval;
+      do
+      {
+        rval= fcntl (server->fd, F_SETFD, FD_CLOEXEC);
+      } while (rval == -1 && (errno == EINTR or errno == EAGAIN));
+#endif
+    }
+
     set_socket_options(server);
 
     /* connect to server */
diff --git a/m4/check_sock_cloexec.m4 b/m4/check_sock_cloexec.m4
new file mode 100644 (file)
index 0000000..3058774
--- /dev/null
@@ -0,0 +1,18 @@
+dnl CHECK_SOCK_CLOEXEC([action-if-found], [action-if-not-found])
+AC_DEFUN([AX_CHECK_SOCK_CLOEXEC], [{
+    AC_MSG_CHECKING(whether SOCK_CLOEXEC is supported)
+    AC_TRY_RUN([/* SOCK_CLOEXEC test */
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int main (int argc, char *argv [])
+{
+    int s= socket(PF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
+    return (s == -1);
+}
+    ],
+    [AC_MSG_RESULT(yes) ; ax_cv_sock_cloexec="yes" ; $1],
+    [AC_MSG_RESULT(no)  ; ax_cv_sock_cloexec="no"  ; $2],
+    [AC_MSG_RESULT(not during cross-compile) ; ax_cv_sock_cloexec="no"]
+    )
+}])