diff --git a/configure.ac b/configure.ac index e7a487da..2dc94cc4 100644 --- a/configure.ac +++ b/configure.ac @@ -180,6 +180,7 @@ AC_CHECK_FUNCS([clock_gettime]) AC_CHECK_LIB([socket], [socket]) AC_CHECK_FUNCS([epoll_create], [AC_DEFINE([HAVE_EPOLL])]) AC_CHECK_FUNCS([kqueue], [AC_DEFINE([HAVE_KQUEUE])]) +AC_CHECK_FUNCS([accept4], [AC_DEFINE([HAVE_ACCEPT4])]) dnl Check if struct sockaddr contains sa_len member AC_CHECK_MEMBERS([struct sockaddr.sa_len], [], [], [ @@ -209,4 +210,3 @@ AC_CONFIG_MACRO_DIR([m4]) AC_OUTPUT([Makefile man/Makefile libdill.pc]) cp confdefs.h config.h - diff --git a/epoll.c.inc b/epoll.c.inc index c925125e..6b428b68 100644 --- a/epoll.c.inc +++ b/epoll.c.inc @@ -62,7 +62,7 @@ int dill_ctx_pollset_init(struct dill_ctx_pollset *ctx) { /* Changelist is empty. */ ctx->changelist = DILL_ENDLIST; /* Create the kernel-side pollset. */ - ctx->efd = epoll_create(1); + ctx->efd = epoll_create1(EPOLL_CLOEXEC); if(dill_slow(ctx->efd < 0)) {err = errno; goto error2;} return 0; error2: diff --git a/fd.c b/fd.c index 92e93887..09130461 100644 --- a/fd.c +++ b/fd.c @@ -22,6 +22,11 @@ */ +#ifdef HAVE_ACCEPT4 +#define _GNU_SOURCE +#include +#endif + #include #include #include @@ -127,12 +132,27 @@ int dill_fd_connect(int s, const struct sockaddr *addr, socklen_t addrlen, return 0; } +#ifdef HAVE_ACCEPT4 +#define _dill_accept(fd, addr, addrlen) accept4((fd), (addr), (addrlen), SOCK_CLOEXEC) +#else +int _dill_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + int as = accept(sockfd, addr, addrlen); + if(dill_fast(as >= 0)) { + int fd_flags = fcntl(as, F_GETFD); + if (dill_fast(fd_flags != -1)) { + fcntl(as, F_SETFD, fd_flags | FD_CLOEXEC); + } + } + return as; +} +#endif + int dill_fd_accept(int s, struct sockaddr *addr, socklen_t *addrlen, int64_t deadline) { int as; while(1) { /* Try to accept new connection synchronously. */ - as = accept(s, addr, addrlen); + as = _dill_accept(s, addr, addrlen); if(dill_fast(as >= 0)) break; /* If connection was aborted by the peer grab the next one. */ @@ -399,8 +419,18 @@ void dill_fd_close(int s) { } int dill_fd_own(int s) { +#ifdef F_DUPFD_CLOEXEC + int n = fcntl(s, F_DUPFD_CLOEXEC, 0); +#else + int fd_flags = fcntl(s, F_GETFD); int n = dup(s); +#endif if(dill_slow(n < 0)) return -1; +#ifndef F_DUPFD_CLOEXEC + if (dill_fast(fd_flags != -1)) { + fcntl(n, F_SETFD, fd_flags); + } +#endif dill_fd_close(s); return n; } @@ -426,4 +456,3 @@ int dill_fd_check(int s, int type, int family1, int family2, int listening) { errno = EINVAL; return -1;} return 0; } -