mirror of
https://github.com/mpv-player/mpv
synced 2025-01-19 05:41:16 +00:00
win32: add tmpfile() replacement
The Windows version of tmpfile is actually pretty broken. It tries to create the file in the root directory of the current drive, which means on Vista and up, it normally fails due to insufficient permissions. Replace it with a version that uses GetTempPath. Also remove the Windows-specific note about automatic deletion of the cache file. FILE_FLAG_DELETE_ON_CLOSE is available in NT, and it should be pretty reliable.
This commit is contained in:
parent
15a882d2ed
commit
5c3f3fd3da
@ -1650,7 +1650,7 @@ Window
|
||||
.. note::
|
||||
|
||||
This does not affect the normal screensaver operation in any way.
|
||||
|
||||
|
||||
``--no-keepaspect``, ``--keepaspect``
|
||||
``--no-keepaspect`` will always stretch the video to window size, and will
|
||||
disable the window manager hints that force the window aspect ratio.
|
||||
@ -2819,8 +2819,7 @@ Cache
|
||||
Instead, an invisible temporary file is created. It depends on your
|
||||
C library where this file is created (usually ``/tmp/``), and whether
|
||||
filename is visible (the ``tmpfile()`` function is used). On some
|
||||
systems, automatic deletion of the cache file might not be guaranteed
|
||||
(like on MS Windows).
|
||||
systems, automatic deletion of the cache file might not be guaranteed.
|
||||
|
||||
If you want to use a file cache, this mode is recommended, because it
|
||||
doesn't break ordered chapters or ``--audio-file``. These modes open
|
||||
|
35
osdep/io.c
35
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;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user