From: Jardel Weyrich Date: Tue, 29 Dec 2009 18:21:26 +0000 (-0200) Subject: Introduced evutil_make_socket_closeonexec() to preserve fd flags for F_SETFD. X-Git-Tag: release-2.0.4-alpha~102 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d0939d2b971417cd5714b535dabfdbd4213b26cb;p=libevent Introduced evutil_make_socket_closeonexec() to preserve fd flags for F_SETFD. Use this to eliminate the various macros that called F_SETFD throughout the code. --- diff --git a/epoll.c b/epoll.c index 03d4bb22..eb429a8f 100644 --- a/epoll.c +++ b/epoll.c @@ -75,15 +75,6 @@ const struct eventop epollops = { 0 }; -#ifdef _EVENT_HAVE_SETFD -#define FD_CLOSEONEXEC(x) do { \ - if (fcntl(x, F_SETFD, 1) == -1) \ - event_warn("fcntl(%d, F_SETFD)", x); \ -} while (0) -#else -#define FD_CLOSEONEXEC(x) -#endif - #define INITIAL_NEVENT 32 #define MAX_NEVENT 4096 @@ -109,7 +100,7 @@ epoll_init(struct event_base *base) return (NULL); } - FD_CLOSEONEXEC(epfd); + evutil_make_socket_closeonexec(epfd); if (!(epollop = mm_calloc(1, sizeof(struct epollop)))) return (NULL); diff --git a/evutil.c b/evutil.c index 3beb4bf7..78e18d42 100644 --- a/evutil.c +++ b/evutil.c @@ -214,6 +214,23 @@ evutil_make_listen_socket_reuseable(evutil_socket_t sock) #endif } +int +evutil_make_socket_closeonexec(evutil_socket_t fd) +{ +#if !defined(WIN32) && defined(_EVENT_HAVE_SETFD) + long flags; + if ((flags = fcntl(fd, F_GETFD, NULL)) < 0) { + event_warn("fcntl(%d, F_GETFD)", fd); + return -1; + } + if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { + event_warn("fcntl(%d, F_SETFD)", fd); + return -1; + } +#endif + return 0; +} + ev_int64_t evutil_strtoll(const char *s, char **endptr, int base) { diff --git a/http.c b/http.c index 26e81ca2..8a919707 100644 --- a/http.c +++ b/http.c @@ -3039,15 +3039,10 @@ bind_socket_ai(struct evutil_addrinfo *ai, int reuse) return (-1); } - if (evutil_make_socket_nonblocking(fd) < 0) - goto out; - -#ifndef WIN32 - if (fcntl(fd, F_SETFD, 1) == -1) { - event_warn("fcntl(F_SETFD)"); - goto out; - } -#endif + if (evutil_make_socket_nonblocking(fd) < 0) + goto out; + if (evutil_make_socket_closeonexec(fd) < 0) + goto out; setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)); if (reuse) diff --git a/include/event2/util.h b/include/event2/util.h index 98c26b61..0f72b6ed 100644 --- a/include/event2/util.h +++ b/include/event2/util.h @@ -167,7 +167,15 @@ int evutil_make_socket_nonblocking(evutil_socket_t sock); @param sock The socket to make reusable @return 0 on success, -1 on failure */ -int evutil_make_listen_socket_reuseable(evutil_socket_t); +int evutil_make_listen_socket_reuseable(evutil_socket_t sock); + +/** Do platform-specific operations as needed to close a socket upon a + successful execution of one of the exec*() functions. + + @param sock The socket to be closed + @return 0 on success, -1 on failure + */ +int evutil_make_socket_closeonexec(evutil_socket_t sock); #ifdef WIN32 /** Do the platform-specific call needed to close a socket returned from diff --git a/listener.c b/listener.c index 7ebfdf08..fee82193 100644 --- a/listener.c +++ b/listener.c @@ -163,14 +163,12 @@ evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb, return NULL; } -#ifndef WIN32 if (flags & LEV_OPT_CLOSE_ON_EXEC) { - if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) { + if (evutil_make_socket_closeonexec(fd) < 0) { EVUTIL_CLOSESOCKET(fd); return NULL; } } -#endif setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&on, sizeof(on)); if (flags & LEV_OPT_REUSEABLE) { diff --git a/signal.c b/signal.c index b0bde815..7c8e09ac 100644 --- a/signal.c +++ b/signal.c @@ -93,15 +93,6 @@ evsig_cb(evutil_socket_t fd, short what, void *arg) event_sock_err(1, fd, "%s: read", __func__); } -#ifdef _EVENT_HAVE_SETFD -#define FD_CLOSEONEXEC(x) do { \ - if (fcntl(x, F_SETFD, 1) == -1) \ - event_warn("fcntl(%d, F_SETFD)", x); \ -} while (0) -#else -#define FD_CLOSEONEXEC(x) -#endif - int evsig_init(struct event_base *base) { @@ -122,8 +113,8 @@ evsig_init(struct event_base *base) return -1; } - FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]); - FD_CLOSEONEXEC(base->sig.ev_signal_pair[1]); + evutil_make_socket_closeonexec(base->sig.ev_signal_pair[0]); + evutil_make_socket_closeonexec(base->sig.ev_signal_pair[1]); base->sig.sh_old = NULL; base->sig.sh_old_max = 0; base->sig.evsig_caught = 0;