From d0939d2b971417cd5714b535dabfdbd4213b26cb Mon Sep 17 00:00:00 2001
From: Jardel Weyrich <jweyrich@gmail.com>
Date: Tue, 29 Dec 2009 16:21:26 -0200
Subject: [PATCH] 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.
---
 epoll.c               | 11 +----------
 evutil.c              | 17 +++++++++++++++++
 http.c                | 13 ++++---------
 include/event2/util.h | 10 +++++++++-
 listener.c            |  4 +---
 signal.c              | 13 ++-----------
 6 files changed, 34 insertions(+), 34 deletions(-)

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;
-- 
2.40.0