Repository: zookeeper Updated Branches: refs/heads/master d857e042f -> 665038e06
ZOOKEEPER-2338: set SOCK_CLOEXEC on socket if defined Author: Radu Brumariu <[email protected]> Reviewers: [email protected] Closes #410 from fr0stbyte/ZOOKEEPER-2338 Change-Id: I7b060a2dc473b34aecc0cfac71d39720369bd635 (cherry picked from commit 508293d6a139eeb59d9dde5b4f72b7043f85350a) Signed-off-by: Patrick Hunt <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/zookeeper/repo Commit: http://git-wip-us.apache.org/repos/asf/zookeeper/commit/665038e0 Tree: http://git-wip-us.apache.org/repos/asf/zookeeper/tree/665038e0 Diff: http://git-wip-us.apache.org/repos/asf/zookeeper/diff/665038e0 Branch: refs/heads/master Commit: 665038e0698cd471a25b7ead4c8a50f767a3e7ed Parents: d857e04 Author: Radu Brumariu <[email protected]> Authored: Wed Dec 6 14:54:24 2017 -0800 Committer: Patrick Hunt <[email protected]> Committed: Wed Dec 6 14:54:44 2017 -0800 ---------------------------------------------------------------------- src/c/CMakeLists.txt | 9 ++++++++ src/c/cmake_config.h.in | 3 +++ src/c/configure.ac | 50 +++++++++++++++++++++++++++++++++++++++----- src/c/src/zookeeper.c | 32 ++++++++++++++++++++-------- 4 files changed, 80 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zookeeper/blob/665038e0/src/c/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/src/c/CMakeLists.txt b/src/c/CMakeLists.txt index 817fc97..a194c8e 100644 --- a/src/c/CMakeLists.txt +++ b/src/c/CMakeLists.txt @@ -59,6 +59,15 @@ else() endif() option(WANT_CPPUNIT "Enables CppUnit and tests" ${DEFAULT_WANT_CPPUNIT}) +# SOCK_CLOEXEC +option(WANT_SOCK_CLOEXEC "Enables SOCK_CLOEXEC on sockets" OFF) +include(CheckSymbolExists) +check_symbol_exists(SOCK_CLOEXEC sys/socket.h HAVE_SOCK_CLOEXEC) +if(WANT_SOCK_CLOEXEC AND HAVE_SOCK_CLOEXEC) + set(SOCK_CLOEXEC_ENABLED 1) +endif() + + # The function `to_have(in out)` converts a header name like `arpa/inet.h` # into an Autotools style preprocessor definition `HAVE_ARPA_INET_H`. # This is then set or unset in `configure_file()` step. http://git-wip-us.apache.org/repos/asf/zookeeper/blob/665038e0/src/c/cmake_config.h.in ---------------------------------------------------------------------- diff --git a/src/c/cmake_config.h.in b/src/c/cmake_config.h.in index 55efd8a..33bcc6c 100644 --- a/src/c/cmake_config.h.in +++ b/src/c/cmake_config.h.in @@ -127,6 +127,9 @@ /* Define to 1 if IPv6 support is available. */ #cmakedefine ZOO_IPV6_ENABLED 1 +/* Define to 1 if SOCK_CLOEXEC is available and wanted */ +#cmakedefine SOCK_CLOEXEC_ENABLED 1 + /* poll() second argument type */ #define POLL_NFDS_TYPE nfds_t http://git-wip-us.apache.org/repos/asf/zookeeper/blob/665038e0/src/c/configure.ac ---------------------------------------------------------------------- diff --git a/src/c/configure.ac b/src/c/configure.ac index b4a1752..9d3674b 100644 --- a/src/c/configure.ac +++ b/src/c/configure.ac @@ -130,11 +130,11 @@ main() else exit(0); } -], AC_MSG_RESULT(yes) - ipv6=yes, - AC_MSG_RESULT(no) - ipv6=no, - AC_MSG_RESULT(no) +], AC_MSG_RESULT(yes) + ipv6=yes, + AC_MSG_RESULT(no) + ipv6=no, + AC_MSG_RESULT(no) ipv6=no) if test x"$ipv6" = xyes; then @@ -142,6 +142,46 @@ if test x"$ipv6" = xyes; then AC_SUBST(USEIPV6) fi +# use SOCK_CLOEXEC if available and wanted +AC_ARG_WITH([sock_cloexec], +[AS_HELP_STRING([--with-sock-cloexec],[build with SOCK_CLOEXEC flag set on the connections])], +[],[with_sock_cloexec=no]) + +AC_MSG_CHECKING([whether SOCK_CLOEXEC is available]) + +AC_TRY_RUN([ /* is SOCK_CLOEXEC available ? */ +#include <sys/types.h> +#include <sys/socket.h> +#include <stdlib.h> +main() +{ +#ifdef SOCK_CLOEXEC + exit(0); +#else + exit(1); +#endif +} +], AC_MSG_RESULT(yes) + has_sock_cloexec=yes, + AC_MSG_RESULT(no) + has_sock_cloexec=no, + AC_MSG_RESULT(no) + has_sock_cloexec=no) + +if test "x$with_sock_cloexec" != xno && test "x$has_sock_cloexec" = xno; then + AC_MSG_WARN([cannot use SOCK_CLOEXEC -- SOCK_CLOEXEC undefined on this platform]) + with_sock_cloexec=no +fi + +if test "x$with_sock_cloexec" != xno; then +AC_MSG_NOTICE([building with SOCK_CLOEXEC]) +else +AC_MSG_NOTICE([building without SOCK_CLOEXEC]) +fi + +AS_IF([test x"$with_sock_cloexec" != xno], [AC_DEFINE([SOCK_CLOEXEC_ENABLED], [1], [Define to 1, if SOCK_CLOEXEC is defined and wanted])]) +AM_CONDITIONAL([SOCK_CLOEXEC_ENABLED],[test "x$with_sock_cloexec" != xno]) + # Determine which libraries we need to use clock_gettime saved_LIBS="$LIBS" LIBS="" http://git-wip-us.apache.org/repos/asf/zookeeper/blob/665038e0/src/c/src/zookeeper.c ---------------------------------------------------------------------- diff --git a/src/c/src/zookeeper.c b/src/c/src/zookeeper.c index af52572..47e2ee1 100644 --- a/src/c/src/zookeeper.c +++ b/src/c/src/zookeeper.c @@ -1700,7 +1700,7 @@ void free_completions(zhandle_t *zh,int callCompletion,int reason) get_auth_completions(&zh->auth_h, &a_list); zoo_unlock_auth(zh); - + a_tmp = &a_list; // chain call user's completion function while (a_tmp->completion != NULL) { @@ -2087,10 +2087,16 @@ static int ping_rw_server(zhandle_t* zh) socket_t sock; int rc; sendsize_t ssize; + int sock_flags; addrvec_peek(&zh->addrs, &zh->addr_rw_server); - sock = socket(zh->addr_rw_server.ss_family, SOCK_STREAM, 0); +#ifdef SOCK_CLOEXEC_ENABLED + sock_flags = SOCK_STREAM | SOCK_CLOEXEC; +#else + sock_flags = SOCK_STREAM; +#endif + sock = socket(zh->addr_rw_server.ss_family, sock_flags, 0); if (sock < 0) { return 0; } @@ -2221,8 +2227,16 @@ static socket_t zookeeper_connect(zhandle_t *zh, int zookeeper_interest(zhandle_t *zh, socket_t *fd, int *interest, struct timeval *tv) { + int sock_flags; int rc = 0; struct timeval now; + +#ifdef SOCK_CLOEXEC_ENABLED + sock_flags = SOCK_STREAM | SOCK_CLOEXEC; +#else + sock_flags = SOCK_STREAM; +#endif + if(zh==0 || fd==0 ||interest==0 || tv==0) return ZBADARGUMENTS; if (is_unrecoverable(zh)) @@ -2272,7 +2286,7 @@ int zookeeper_interest(zhandle_t *zh, socket_t *fd, int *interest, // No need to delay -- grab the next server and attempt connection zoo_cycle_next_server(zh); } - zh->fd = socket(zh->addr_cur.ss_family, SOCK_STREAM, 0); + zh->fd = socket(zh->addr_cur.ss_family, sock_flags, 0); if (zh->fd < 0) { rc = handle_socket_error_msg(zh, __LINE__, @@ -2607,7 +2621,7 @@ static int deserialize_multi(zhandle_t *zh, int xid, completion_list_t *cptr, st deserialize_response(zh, entry->c.type, xid, mhdr.type == -1, mhdr.err, entry, ia); deserialize_MultiHeader(ia, "multiheader", &mhdr); - //While deserializing the response we must destroy completion entry for each operation in + //While deserializing the response we must destroy completion entry for each operation in //the zoo_multi transaction. Otherwise this results in memory leak when client invokes zoo_multi //operation. destroy_completion_entry(entry); @@ -3524,7 +3538,7 @@ int zoo_acreate(zhandle_t *zh, const char *path, const char *value, struct RequestHeader h = {get_xid(), ZOO_CREATE_OP}; struct CreateRequest req; - int rc = CreateRequest_init(zh, &req, + int rc = CreateRequest_init(zh, &req, path, value, valuelen, acl_entries, flags); if (rc != ZOK) { return rc; @@ -3632,7 +3646,7 @@ int zoo_awexists(zhandle_t *zh, const char *path, struct oarchive *oa; struct RequestHeader h = {get_xid(), ZOO_EXISTS_OP}; struct ExistsRequest req; - int rc = Request_path_watch_init(zh, 0, &req.path, path, + int rc = Request_path_watch_init(zh, 0, &req.path, path, &req.watch, watcher != NULL); if (rc != ZOK) { return rc; @@ -3666,7 +3680,7 @@ static int zoo_awget_children_(zhandle_t *zh, const char *path, struct oarchive *oa; struct RequestHeader h = {get_xid(), ZOO_GETCHILDREN_OP}; struct GetChildrenRequest req ; - int rc = Request_path_watch_init(zh, 0, &req.path, path, + int rc = Request_path_watch_init(zh, 0, &req.path, path, &req.watch, watcher != NULL); if (rc != ZOK) { return rc; @@ -3714,7 +3728,7 @@ static int zoo_awget_children2_(zhandle_t *zh, const char *path, struct oarchive *oa; struct RequestHeader h = {get_xid(), ZOO_GETCHILDREN2_OP}; struct GetChildren2Request req ; - int rc = Request_path_watch_init(zh, 0, &req.path, path, + int rc = Request_path_watch_init(zh, 0, &req.path, path, &req.watch, watcher != NULL); if (rc != ZOK) { return rc; @@ -4090,7 +4104,7 @@ void zoo_create_op_init(zoo_op_t *op, const char *path, const char *value, } void zoo_create2_op_init(zoo_op_t *op, const char *path, const char *value, - int valuelen, const struct ACL_vector *acl, int flags, + int valuelen, const struct ACL_vector *acl, int flags, char *path_buffer, int path_buffer_len) { assert(op);
