diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d2a2c05a..aa16a7d91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,7 @@ check_symbol_exists(sys_signame signal.h HAVE_SIGNAME) include(CheckFunctionExists) check_function_exists(backtrace HAVE_BACKTRACE) +check_function_exists(accept4 HAVE_ACCEPT4) include(TestBigEndian) test_big_endian(HAVE_BIG_ENDIAN) diff --git a/config.h.in b/config.h.in index f1dc18bd9..3b5ba96ef 100644 --- a/config.h.in +++ b/config.h.in @@ -12,6 +12,8 @@ #cmakedefine HAVE_BACKTRACE +#cmakedefine HAVE_ACCEPT4 + #cmakedefine HAVE_BIG_ENDIAN #cmakedefine HAVE_LOGGING diff --git a/include/cc_define.h b/include/cc_define.h index b521b133e..a4dda714d 100644 --- a/include/cc_define.h +++ b/include/cc_define.h @@ -54,6 +54,10 @@ extern "C" { # define CC_BACKTRACE 1 #endif +#ifdef HAVE_ACCEPT4 +# define CC_ACCEPT4 1 +#endif + #ifdef HAVE_DEBUG_MM #define CC_DEBUG_MM 1 #endif diff --git a/src/channel/cc_tcp.c b/src/channel/cc_tcp.c index d482ac9c0..bbd685d2f 100644 --- a/src/channel/cc_tcp.c +++ b/src/channel/cc_tcp.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -321,7 +322,11 @@ _tcp_accept(struct tcp_conn *sc) ASSERT(sc->sd > 0); for (;;) { /* we accept at most one tcp_conn with the 'break' at the end */ +#ifdef CC_ACCEPT4 + sd = accept4(sc->sd, NULL, NULL, SOCK_NONBLOCK); +#else sd = accept(sc->sd, NULL, NULL); +#endif /* CC_ACCEPT4 */ if (sd < 0) { if (errno == EINTR) { log_debug("accept on sd %d not ready: eintr", sc->sd); @@ -360,11 +365,13 @@ tcp_accept(struct tcp_conn *sc, struct tcp_conn *c) c->level = CHANNEL_BASE; c->state = CHANNEL_ESTABLISHED; +#ifndef CC_ACCEPT4 /* if we have accept4, nonblock will already have been set */ ret = tcp_set_nonblocking(sd); if (ret < 0) { log_warn("set nonblock on sd %d failed, ignored: %s", sd, strerror(errno)); } +#endif ret = tcp_set_tcpnodelay(sd); if (ret < 0) {