[FFmpeg-devel] [PATCH 1/2] avutil/file: Move av_tempfile() to avutil/file_open ff_tempfile()

Michael Niedermayer michael at niedermayer.cc
Wed Mar 9 15:37:14 CET 2016


document the issue with av_tempfile()

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
---
 libavcodec/libxvid.h  |    2 --
 libavutil/file.c      |   48 ++--------------------------------------
 libavutil/file.h      |    1 +
 libavutil/file_open.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++++
 libavutil/internal.h  |   14 ++++++++++++
 5 files changed, 76 insertions(+), 48 deletions(-)

diff --git a/libavcodec/libxvid.h b/libavcodec/libxvid.h
index bffe07d..ef9a5a9 100644
--- a/libavcodec/libxvid.h
+++ b/libavcodec/libxvid.h
@@ -26,6 +26,4 @@
  * common functions for use with the Xvid wrappers
  */
 
-int ff_tempfile(const char *prefix, char **filename);
-
 #endif /* AVCODEC_LIBXVID_H */
diff --git a/libavutil/file.c b/libavutil/file.c
index 2a06be4..25381b1 100644
--- a/libavutil/file.c
+++ b/libavutil/file.c
@@ -137,52 +137,8 @@ void av_file_unmap(uint8_t *bufptr, size_t size)
 #endif
 }
 
-int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx)
-{
-    FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
-    int fd = -1;
-#if !HAVE_MKSTEMP
-    void *ptr= tempnam(NULL, prefix);
-    if(!ptr)
-        ptr= tempnam(".", prefix);
-    *filename = av_strdup(ptr);
-#undef free
-    free(ptr);
-#else
-    size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */
-    *filename  = av_malloc(len);
-#endif
-    /* -----common section-----*/
-    if (!*filename) {
-        av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n");
-        return AVERROR(ENOMEM);
-    }
-#if !HAVE_MKSTEMP
-#   ifndef O_BINARY
-#       define O_BINARY 0
-#   endif
-#   ifndef O_EXCL
-#       define O_EXCL 0
-#   endif
-    fd = open(*filename, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600);
-#else
-    snprintf(*filename, len, "/tmp/%sXXXXXX", prefix);
-    fd = mkstemp(*filename);
-#ifdef _WIN32
-    if (fd < 0) {
-        snprintf(*filename, len, "./%sXXXXXX", prefix);
-        fd = mkstemp(*filename);
-    }
-#endif
-#endif
-    /* -----common section-----*/
-    if (fd < 0) {
-        int err = AVERROR(errno);
-        av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename);
-        av_freep(filename);
-        return err;
-    }
-    return fd; /* success */
+int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx) {
+    return avpriv_tempfile(prefix, filename, log_offset, log_ctx);
 }
 
 #ifdef TEST
diff --git a/libavutil/file.h b/libavutil/file.h
index e931be7..8666c7b 100644
--- a/libavutil/file.h
+++ b/libavutil/file.h
@@ -62,6 +62,7 @@ void av_file_unmap(uint8_t *bufptr, size_t size);
  * @note On very old libcs it is necessary to set a secure umask before
  *       calling this, av_tempfile() can't call umask itself as it is used in
  *       libraries and could interfere with the calling application.
+ * @deprecated as fd numbers cannot be passed saftely between libs on some platforms
  */
 int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx);
 
diff --git a/libavutil/file_open.c b/libavutil/file_open.c
index 9e76127..6e58cc1 100644
--- a/libavutil/file_open.c
+++ b/libavutil/file_open.c
@@ -92,6 +92,65 @@ int avpriv_open(const char *filename, int flags, ...)
     return fd;
 }
 
+typedef struct FileLogContext {
+    const AVClass *class;
+    int   log_offset;
+    void *log_ctx;
+} FileLogContext;
+
+static const AVClass file_log_ctx_class = {
+    "TEMPFILE", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT,
+    offsetof(FileLogContext, log_offset), offsetof(FileLogContext, log_ctx)
+};
+
+int avpriv_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx)
+{
+    FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
+    int fd = -1;
+#if !HAVE_MKSTEMP
+    void *ptr= tempnam(NULL, prefix);
+    if(!ptr)
+        ptr= tempnam(".", prefix);
+    *filename = av_strdup(ptr);
+#undef free
+    free(ptr);
+#else
+    size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */
+    *filename  = av_malloc(len);
+#endif
+    /* -----common section-----*/
+    if (!*filename) {
+        av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n");
+        return AVERROR(ENOMEM);
+    }
+#if !HAVE_MKSTEMP
+#   ifndef O_BINARY
+#       define O_BINARY 0
+#   endif
+#   ifndef O_EXCL
+#       define O_EXCL 0
+#   endif
+    fd = open(*filename, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600);
+#else
+    snprintf(*filename, len, "/tmp/%sXXXXXX", prefix);
+    fd = mkstemp(*filename);
+#ifdef _WIN32
+    if (fd < 0) {
+        snprintf(*filename, len, "./%sXXXXXX", prefix);
+        fd = mkstemp(*filename);
+    }
+#endif
+#endif
+    /* -----common section-----*/
+    if (fd < 0) {
+        int err = AVERROR(errno);
+        av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename);
+        av_freep(filename);
+        return err;
+    }
+    return fd; /* success */
+}
+
 FILE *av_fopen_utf8(const char *path, const char *mode)
 {
     int fd;
diff --git a/libavutil/internal.h b/libavutil/internal.h
index c4bcf37..da76ca2 100644
--- a/libavutil/internal.h
+++ b/libavutil/internal.h
@@ -244,6 +244,7 @@ void avpriv_request_sample(void *avc,
 #endif
 
 #define avpriv_open ff_open
+#define avpriv_tempfile ff_tempfile
 #define PTRDIFF_SPECIFIER "Id"
 #define SIZE_SPECIFIER "Iu"
 #else
@@ -319,6 +320,19 @@ static av_always_inline float ff_exp10f(float x)
 av_warn_unused_result
 int avpriv_open(const char *filename, int flags, ...);
 
+/**
+ * Wrapper to work around the lack of mkstemp() on mingw.
+ * Also, tries to create file in /tmp first, if possible.
+ * *prefix can be a character constant; *filename will be allocated internally.
+ * @return file descriptor of opened file (or negative value corresponding to an
+ * AVERROR code on error)
+ * and opened file name in **filename.
+ * @note On very old libcs it is necessary to set a secure umask before
+ *       calling this, av_tempfile() can't call umask itself as it is used in
+ *       libraries and could interfere with the calling application.
+ */
+int avpriv_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx);
+
 int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt);
 
 static av_always_inline av_const int avpriv_mirror(int x, int w)
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list