[vlc-commits] filesystem: add vlc_memfd() helper

Rémi Denis-Courmont git at videolan.org
Mon Aug 24 20:14:06 CEST 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Aug 24 19:14:02 2015 +0300| [ab29a4598b890acdeb48e3066ae06a6c818c7f3e] | committer: Rémi Denis-Courmont

filesystem: add vlc_memfd() helper

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ab29a4598b890acdeb48e3066ae06a6c818c7f3e
---

 configure.ac           |    2 +-
 include/vlc_fs.h       |   13 +++++++++++++
 src/libvlccore.sym     |    1 +
 src/os2/filesystem.c   |    6 ++++++
 src/posix/filesystem.c |   29 +++++++++++++++++++++++++++++
 src/win32/filesystem.c |   20 ++++++++++++++++++++
 6 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 83a6ad9..d38f8e8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -536,7 +536,7 @@ need_libc=false
 
 dnl Check for usual libc functions
 AC_CHECK_DECLS([nanosleep],,,[#include <time.h>])
-AC_CHECK_FUNCS([daemon fcntl fstatvfs fork getenv getpwuid_r isatty lstat memalign mmap open_memstream openat pread posix_fadvise posix_madvise setlocale stricmp strnicmp strptime uselocale pthread_cond_timedwait_monotonic_np pthread_condattr_setclock])
+AC_CHECK_FUNCS([daemon fcntl fstatvfs fork getenv getpwuid_r isatty lstat memalign mkostemp mmap open_memstream openat pread posix_fadvise posix_madvise setlocale stricmp strnicmp strptime uselocale pthread_cond_timedwait_monotonic_np pthread_condattr_setclock])
 AC_REPLACE_FUNCS([atof atoll dirfd fdopendir ffsll flockfile fsync getdelim getpid lldiv nrand48 poll posix_memalign rewind setenv strcasecmp strcasestr strdup strlcpy strndup strnlen strsep strtof strtok_r strtoll swab tdestroy strverscmp])
 AC_CHECK_FUNCS(fdatasync,,
   [AC_DEFINE(fdatasync, fsync, [Alias fdatasync() to fsync() if missing.])
diff --git a/include/vlc_fs.h b/include/vlc_fs.h
index bd8731a..8acb6b1 100644
--- a/include/vlc_fs.h
+++ b/include/vlc_fs.h
@@ -94,6 +94,19 @@ VLC_API int vlc_dup(int) VLC_USED;
 VLC_API int vlc_pipe(int [2]) VLC_USED;
 
 /**
+ * Creates an anonymous regular file descriptor, i.e. a descriptor for a
+ * temporary file.
+ *
+ * The file is initially empty. The storage space is automatically reclaimed
+ * when all file descriptors referencing it are closed.
+ *
+ * The new file descriptor has the close-on-exec flag preset.
+ *
+ * @return a file descriptor on success, -1 on error (see errno)
+ */
+VLC_API int vlc_memfd(void) VLC_USED;
+
+/**
  * Writes data to a file descriptor. Unlike write(), if EPIPE error occurs,
  * this function does not generate a SIGPIPE signal.
  * @note If the file descriptor is known to be neither a pipe/FIFO nor a
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 1efa017..1ee6ecc 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -450,6 +450,7 @@ vlc_mkdir
 vlc_mkstemp
 vlc_open
 vlc_openat
+vlc_memfd
 vlc_opendir
 vlc_readdir
 vlc_scandir
diff --git a/src/os2/filesystem.c b/src/os2/filesystem.c
index e0a635c..2c42a2e 100644
--- a/src/os2/filesystem.c
+++ b/src/os2/filesystem.c
@@ -79,6 +79,12 @@ int vlc_openat (int dir, const char *filename, int flags, ...)
     return -1;
 }
 
+int vlc_memfd (void)
+{
+    errno = ENOSYS;
+    return -1;
+}
+
 int vlc_mkdir (const char *dirname, mode_t mode)
 {
     char *locname = ToLocaleDup (dirname);
diff --git a/src/posix/filesystem.c b/src/posix/filesystem.c
index 4e50c91..bab9e85 100644
--- a/src/posix/filesystem.c
+++ b/src/posix/filesystem.c
@@ -98,6 +98,35 @@ int vlc_openat (int dir, const char *filename, int flags, ...)
     return fd;
 }
 
+int vlc_memfd (void)
+{
+    int fd;
+#ifdef O_TMPFILE
+    fd = vlc_open ("/tmp", O_RDWR|O_TMPFILE, S_IRUSR|S_IWUSR);
+    if (fd != -1)
+        return fd;
+    /* ENOENT means either /tmp is missing (!) or the kernel does not support
+     * O_TMPFILE. EISDIR means /tmp exists but the kernel does not support
+     * O_TMPFILE. EOPNOTSUPP means the kernel supports O_TMPFILE but the /tmp
+     * filesystem does not. Do not fallback on other errors. */
+    if (errno != ENOENT && errno != EISDIR && errno != EOPNOTSUPP)
+        return -1;
+#endif
+
+    char bufpath[] = "/tmp/"PACKAGE_NAME"XXXXXX";
+
+#ifdef HAVE_MKOSTEMP
+    fd = mkostemp (bufpath, O_CLOEXEC);
+#else
+    fd = mkstemp (bufpath);
+#endif
+    if (fd != -1)
+    {
+        fcntl (fd, F_SETFD, FD_CLOEXEC);
+        unlink (bufpath);
+    }
+    return fd;
+}
 
 int vlc_mkdir (const char *dirname, mode_t mode)
 {
diff --git a/src/win32/filesystem.c b/src/win32/filesystem.c
index 0c40b6b..62c4439 100644
--- a/src/win32/filesystem.c
+++ b/src/win32/filesystem.c
@@ -104,6 +104,26 @@ int vlc_openat (int dir, const char *filename, int flags, ...)
     return -1;
 }
 
+int vlc_memfd (void)
+{
+#if 0
+    int fd, err;
+
+    FILE *stream = tmpfile();
+    if (stream == NULL)
+        return -1;
+
+    fd = vlc_dup(fileno(stream));
+    err = errno;
+    fclose(stream);
+    errno = err;
+    return fd;
+#else /* Not currently used */
+    errno = ENOSYS;
+    return -1;
+#endif
+}
+
 int vlc_mkdir( const char *dirname, mode_t mode )
 {
     wchar_t *wpath = widen_path (dirname);



More information about the vlc-commits mailing list