eina: add an API to correctly do close on exec.
authorCedric BAIL <cedric@osg.samsung.com>
Tue, 18 Apr 2017 23:53:26 +0000 (16:53 -0700)
committerCedric BAIL <cedric@osg.samsung.com>
Tue, 18 Apr 2017 23:53:26 +0000 (16:53 -0700)
src/lib/eina/eina_file.h
src/lib/eina/eina_file_common.c

index e5098be..3a0b3dc 100644 (file)
@@ -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"
 
 /**
index cd842a7..4b94d1d 100644 (file)
@@ -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
+}