From d4758957f0b472a5f247004862fef55f58edcc8f Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Tue, 5 Jun 2012 23:30:45 +0100 Subject: [PATCH] Fix for close on exec for socket. --- configure.ac | 3 +++ libmemcached/connect.cc | 23 ++++++++++++++++++++++- m4/check_sock_cloexec.m4 | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 m4/check_sock_cloexec.m4 diff --git a/configure.ac b/configure.ac index e2d36814..588e1f61 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/libmemcached/connect.cc b/libmemcached/connect.cc index 34e72f76..8e8092c8 100644 --- a/libmemcached/connect.cc +++ b/libmemcached/connect.cc @@ -42,6 +42,10 @@ #include #include +#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 index 00000000..30587745 --- /dev/null +++ b/m4/check_sock_cloexec.m4 @@ -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 +#include + +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"] + ) +}]) -- 2.30.2