From: Sumit Bose Date: Thu, 11 Aug 2011 10:30:48 +0000 (+0200) Subject: tevent: Set FD_CLOEXEC on epoll handle X-Git-Url: http://git.samba.org/?a=commitdiff_plain;h=158b208dfd75c04698f9f9196161322b16a020a2;p=mat%2Fsamba.git tevent: Set FD_CLOEXEC on epoll handle If an application using libtevent starts a new process the epoll file descriptor is leaked to the new process if the event context is not freed explicitly. By setting FD_CLOEXEC this is not needed anymore. Signed-off-by: Simo Sorce --- diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c index 3ab8283955..33e1d3f20f 100644 --- a/lib/tevent/tevent_epoll.c +++ b/lib/tevent/tevent_epoll.c @@ -78,11 +78,20 @@ static int epoll_ctx_destructor(struct epoll_event_context *epoll_ev) static int epoll_init_ctx(struct epoll_event_context *epoll_ev) { epoll_ev->epoll_fd = epoll_create(64); - epoll_ev->pid = getpid(); - talloc_set_destructor(epoll_ev, epoll_ctx_destructor); if (epoll_ev->epoll_fd == -1) { + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, + "Failed to create epoll handle.\n"); return -1; } + + if (!ev_set_close_on_exec(epoll_ev->epoll_fd)) { + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_WARNING, + "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); + } + + epoll_ev->pid = getpid(); + talloc_set_destructor(epoll_ev, epoll_ctx_destructor); + return 0; } @@ -108,6 +117,12 @@ static void epoll_check_reopen(struct epoll_event_context *epoll_ev) "Failed to recreate epoll handle after fork\n"); return; } + + if (!ev_set_close_on_exec(epoll_ev->epoll_fd)) { + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_WARNING, + "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); + } + epoll_ev->pid = getpid(); for (fde=epoll_ev->ev->fd_events;fde;fde=fde->next) { epoll_add_event(epoll_ev, fde); diff --git a/lib/tevent/tevent_standard.c b/lib/tevent/tevent_standard.c index 35f7ded9b7..e2ca44f9c2 100644 --- a/lib/tevent/tevent_standard.c +++ b/lib/tevent/tevent_standard.c @@ -100,6 +100,17 @@ static int epoll_ctx_destructor(struct std_event_context *std_ev) static void epoll_init_ctx(struct std_event_context *std_ev) { std_ev->epoll_fd = epoll_create(64); + if (std_ev->epoll_fd == -1) { + tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL, + "Failed to create epoll handle.\n"); + return; + } + + if (!ev_set_close_on_exec(std_ev->epoll_fd)) { + tevent_debug(std_ev->ev, TEVENT_DEBUG_WARNING, + "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); + } + std_ev->pid = getpid(); talloc_set_destructor(std_ev, epoll_ctx_destructor); } @@ -126,6 +137,12 @@ static void epoll_check_reopen(struct std_event_context *std_ev) "Failed to recreate epoll handle after fork\n"); return; } + + if (!ev_set_close_on_exec(std_ev->epoll_fd)) { + tevent_debug(std_ev->ev, TEVENT_DEBUG_WARNING, + "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); + } + std_ev->pid = getpid(); for (fde=std_ev->ev->fd_events;fde;fde=fde->next) { epoll_add_event(std_ev, fde); diff --git a/lib/tevent/tevent_util.c b/lib/tevent/tevent_util.c index f78cd8f707..16af8f3b90 100644 --- a/lib/tevent/tevent_util.c +++ b/lib/tevent/tevent_util.c @@ -88,3 +88,20 @@ int ev_set_blocking(int fd, bool set) return fcntl( fd, F_SETFL, val); #undef FLAG_TO_SET } + +bool ev_set_close_on_exec(int fd) +{ +#ifdef FD_CLOEXEC + int val; + + val = fcntl(fd, F_GETFD, 0); + if (val >= 0) { + val |= FD_CLOEXEC; + val = fcntl(fd, F_SETFD, val); + if (val != -1) { + return true; + } + } +#endif + return false; +} diff --git a/lib/tevent/tevent_util.h b/lib/tevent/tevent_util.h index 46a4506dac..311be604a0 100644 --- a/lib/tevent/tevent_util.h +++ b/lib/tevent/tevent_util.h @@ -183,6 +183,7 @@ do { \ const char **ev_str_list_add(const char **list, const char *s); int ev_set_blocking(int fd, bool set); size_t ev_str_list_length(const char **list); +bool ev_set_close_on_exec(int fd); /* Defined here so we can build against older talloc versions that don't * have this define yet. */