summaryrefslogtreecommitdiffstats
path: root/osdep
diff options
context:
space:
mode:
Diffstat (limited to 'osdep')
-rw-r--r--osdep/io.c35
-rw-r--r--osdep/io.h2
2 files changed, 37 insertions, 0 deletions
diff --git a/osdep/io.c b/osdep/io.c
index e0caa56f79..819cdcbf69 100644
--- a/osdep/io.c
+++ b/osdep/io.c
@@ -310,6 +310,41 @@ int mp_mkdir(const char *path, int mode)
return res;
}
+FILE *mp_tmpfile(void)
+{
+ // Reserve a file name in the format %TMP%\mpvXXXX.TMP
+ wchar_t tmp_path[MAX_PATH + 1];
+ if (!GetTempPathW(MAX_PATH + 1, tmp_path))
+ return NULL;
+ wchar_t tmp_name[MAX_PATH + 1];
+ if (!GetTempFileNameW(tmp_path, L"mpv", 0, tmp_name))
+ return NULL;
+
+ // Create the file. FILE_ATTRIBUTE_TEMPORARY indicates the file will be
+ // short-lived. Windows should avoid flushing it to disk while there is
+ // sufficient cache.
+ HANDLE file = CreateFileW(tmp_name, GENERIC_READ | GENERIC_WRITE | DELETE,
+ FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
+ if (file == INVALID_HANDLE_VALUE) {
+ DeleteFileW(tmp_name);
+ return NULL;
+ }
+
+ int fd = _open_osfhandle((intptr_t)file, 0);
+ if (fd < 0) {
+ CloseHandle(file);
+ return NULL;
+ }
+ FILE *fp = fdopen(fd, "w+b");
+ if (!fp) {
+ close(fd);
+ return NULL;
+ }
+
+ return fp;
+}
+
static char **utf8_environ;
static void *utf8_environ_ctx;
diff --git a/osdep/io.h b/osdep/io.h
index 306e2ac6ec..ae3cdc1802 100644
--- a/osdep/io.h
+++ b/osdep/io.h
@@ -75,6 +75,7 @@ DIR *mp_opendir(const char *path);
struct dirent *mp_readdir(DIR *dir);
int mp_closedir(DIR *dir);
int mp_mkdir(const char *path, int mode);
+FILE *mp_tmpfile(void);
char *mp_getenv(const char *name);
typedef struct {
@@ -101,6 +102,7 @@ void mp_globfree(mp_glob_t *pglob);
#define readdir(...) mp_readdir(__VA_ARGS__)
#define closedir(...) mp_closedir(__VA_ARGS__)
#define mkdir(...) mp_mkdir(__VA_ARGS__)
+#define tmpfile(...) mp_tmpfile(__VA_ARGS__)
#define getenv(...) mp_getenv(__VA_ARGS__)
#ifndef GLOB_NOMATCH