cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=9d8549f7a302e0c122baaa0ea2f15d7fe6d99589

commit 9d8549f7a302e0c122baaa0ea2f15d7fe6d99589
Author: Cedric BAIL <ced...@osg.samsung.com>
Date:   Tue Apr 18 16:53:26 2017 -0700

    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 e5098be..3a0b3dc 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 cd842a7..4b94d1d 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
+}

-- 


Reply via email to