From 9d8549f7a302e0c122baaa0ea2f15d7fe6d99589 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Tue, 18 Apr 2017 16:53:26 -0700 Subject: [PATCH] eina: add an API to correctly do close on exec. --- src/lib/eina/eina_file.h | 13 +++++++++++ src/lib/eina/eina_file_common.c | 38 +++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/lib/eina/eina_file.h b/src/lib/eina/eina_file.h index e5098be065..3a0b3dcfb4 100644 --- a/src/lib/eina/eina_file.h +++ b/src/lib/eina/eina_file.h @@ -753,6 +753,19 @@ static inline size_t eina_file_path_join(char *dst, */ EAPI Eina_Bool eina_file_unlink(const char *pathname); +/** + * @brief Make sure a file descriptor will be closed on exec. + * @details This function is a wrapper around the fnctl() system call. It makes sure + * that the fd will be closed whenever exec is called. + * + * @param fd File descriptor to enforce close on exec on. + * @param on #EINA_TRUE will turn close on exec on, #EINA_FALSE will turn it off. + * @return #EINA_TRUE if it will be closed on exec, #EINA_FALSE otherwise.. + * + * @since 1.20 + */ +EAPI Eina_Bool eina_file_close_on_exec(int fd, Eina_Bool on); + #include "eina_inline_file.x" /** diff --git a/src/lib/eina/eina_file_common.c b/src/lib/eina/eina_file_common.c index cd842a7572..4b94d1d20c 100644 --- a/src/lib/eina/eina_file_common.c +++ b/src/lib/eina/eina_file_common.c @@ -1095,3 +1095,41 @@ eina_file_shutdown(void) _eina_file_log_dom = -1; return EINA_TRUE; } + +EAPI Eina_Bool +eina_file_close_on_exec(int fd, Eina_Bool on) +{ +#ifdef HAVE_FCNTL + int flags; + + flags = fcntl(fd, F_GETFD); + if (flags < 0) + { + int errno_backup = errno; + ERR("%#x = fcntl(%d, F_GETFD): %s", flags, fd, strerror(errno)); + errno = errno_backup; + return EINA_FALSE; + } + + if (on) + flags |= FD_CLOEXEC; + else + flags &= (~flags); + + if (fcntl(fd, F_SETFD, flags) == -1) + { + int errno_backup = errno; + ERR("fcntl(%d, F_SETFD, %#x): %s", fd, flags, strerror(errno)); + errno = errno_backup; + return EINA_FALSE; + } + return EINA_TRUE; +#else + static Eina_Bool statement = EINA_FALSE; + + if (!statement) + ERR("fcntl is not available on your platform. fd may leak when using exec."); + statement = EINA_TRUE; + return EINA_TRUE; +#endif +}