avutil/file: Move av_tempfile() to avutil/file_open ff_tempfile()

document the issue with av_tempfile()

Tested-by: Hendrik Leppkes <h.leppkes@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer 2016-03-09 14:33:25 +01:00
parent 5d64ba9d18
commit b4f59beeb4
5 changed files with 76 additions and 48 deletions

View File

@ -26,6 +26,4 @@
* common functions for use with the Xvid wrappers * common functions for use with the Xvid wrappers
*/ */
int ff_tempfile(const char *prefix, char **filename);
#endif /* AVCODEC_LIBXVID_H */ #endif /* AVCODEC_LIBXVID_H */

View File

@ -137,52 +137,8 @@ void av_file_unmap(uint8_t *bufptr, size_t size)
#endif #endif
} }
int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx) int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx) {
{ return avpriv_tempfile(prefix, filename, log_offset, 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 */
} }
#ifdef TEST #ifdef TEST

View File

@ -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 * @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 * calling this, av_tempfile() can't call umask itself as it is used in
* libraries and could interfere with the calling application. * 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); int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx);

View File

@ -92,6 +92,65 @@ int avpriv_open(const char *filename, int flags, ...)
return fd; 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) FILE *av_fopen_utf8(const char *path, const char *mode)
{ {
int fd; int fd;

View File

@ -244,6 +244,7 @@ void avpriv_request_sample(void *avc,
#endif #endif
#define avpriv_open ff_open #define avpriv_open ff_open
#define avpriv_tempfile ff_tempfile
#define PTRDIFF_SPECIFIER "Id" #define PTRDIFF_SPECIFIER "Id"
#define SIZE_SPECIFIER "Iu" #define SIZE_SPECIFIER "Iu"
#else #else
@ -319,6 +320,19 @@ static av_always_inline float ff_exp10f(float x)
av_warn_unused_result av_warn_unused_result
int avpriv_open(const char *filename, int flags, ...); 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); 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) static av_always_inline av_const int avpriv_mirror(int x, int w)