diff options
Diffstat (limited to 'misc')
-rw-r--r-- | misc/bstr.c | 1 | ||||
-rw-r--r-- | misc/bstr.h | 2 | ||||
-rw-r--r-- | misc/charset_conv.c | 4 | ||||
-rw-r--r-- | misc/io_utils.c | 4 | ||||
-rw-r--r-- | misc/language.c | 1 | ||||
-rw-r--r-- | misc/path_utils.c | 87 | ||||
-rw-r--r-- | misc/thread_tools.c | 5 |
7 files changed, 93 insertions, 11 deletions
diff --git a/misc/bstr.c b/misc/bstr.c index abe688bd14..379b2ed22d 100644 --- a/misc/bstr.c +++ b/misc/bstr.c @@ -16,7 +16,6 @@ */ #include <string.h> -#include <strings.h> #include <assert.h> #include <stdarg.h> #include <stdint.h> diff --git a/misc/bstr.h b/misc/bstr.h index 3da4f1639f..aaae7d695c 100644 --- a/misc/bstr.h +++ b/misc/bstr.h @@ -56,6 +56,8 @@ static inline struct bstr bstrdup(void *talloc_ctx, struct bstr str) return r; } +#define bstr0_lit(s) {(unsigned char *)(s), sizeof("" s) - 1} + static inline struct bstr bstr0(const char *s) { return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0}; diff --git a/misc/charset_conv.c b/misc/charset_conv.c index b54f6362b6..2363ccaf80 100644 --- a/misc/charset_conv.c +++ b/misc/charset_conv.c @@ -21,11 +21,11 @@ #include <stdlib.h> #include <errno.h> -#include <strings.h> #include <assert.h> #include "config.h" +#include "common/common.h" #include "common/msg.h" #if HAVE_UCHARDET @@ -165,7 +165,7 @@ bstr mp_iconv_to_utf8(struct mp_log *log, bstr buf, const char *cp, int flags) // Force CP949 over EUC-KR since iconv distinguishes them and // EUC-KR causes error on CP949 encoded data if (strcasecmp(cp, "EUC-KR") == 0) - cp = "CP949"; + cp = "CP949"; iconv_t icdsc; if ((icdsc = iconv_open("UTF-8", cp)) == (iconv_t) (-1)) { diff --git a/misc/io_utils.c b/misc/io_utils.c index c973cee0e4..fafed772cc 100644 --- a/misc/io_utils.c +++ b/misc/io_utils.c @@ -23,10 +23,10 @@ #include <stdlib.h> #include <sys/types.h> #include <limits.h> -#include <unistd.h> #include "mpv_talloc.h" #include "config.h" +#include "common/common.h" #include "misc/random.h" #include "misc/io_utils.h" #include "osdep/io.h" @@ -63,7 +63,7 @@ bool mp_save_to_file(const char *filepath, const void *data, size_t size) bool result = false; char *tmp = talloc_asprintf(NULL, "%sXXXXXX", filepath); - int fd = mkstemp(tmp); + int fd = mp_mkostemps(tmp, 0, O_CLOEXEC); if (fd < 0) goto done; FILE *cache = fdopen(fd, "wb"); diff --git a/misc/language.c b/misc/language.c index 92857f75b4..b94dd8eaf2 100644 --- a/misc/language.c +++ b/misc/language.c @@ -26,7 +26,6 @@ #include <stddef.h> #include <stdlib.h> #include <string.h> -#include <strings.h> static const struct lang { char match[4]; diff --git a/misc/path_utils.c b/misc/path_utils.c index 14b4a97031..7252834e7e 100644 --- a/misc/path_utils.c +++ b/misc/path_utils.c @@ -24,16 +24,21 @@ #include <stdbool.h> #include <sys/types.h> #include <sys/stat.h> -#include <unistd.h> #include <errno.h> #include "config.h" #include "mpv_talloc.h" +#include "common/common.h" #include "osdep/io.h" #include "misc/ctype.h" #include "misc/path_utils.h" +#if defined(HAVE_PATHCCH) && HAVE_PATHCCH +#include <windows.h> +#include <pathcch.h> +#endif + char *mp_basename(const char *path) { char *s; @@ -151,10 +156,88 @@ char *mp_getcwd(void *talloc_ctx) char *mp_normalize_path(void *talloc_ctx, const char *path) { + if (!path) + return NULL; + if (mp_is_url(bstr0(path))) return talloc_strdup(talloc_ctx, path); - return mp_path_join(talloc_ctx, mp_getcwd(talloc_ctx), path); + if (!mp_path_is_absolute(bstr0(path))) { + char *cwd = mp_getcwd(talloc_ctx); + if (!cwd) + return NULL; + path = mp_path_join(talloc_ctx, cwd, path); + } + +#if defined(HAVE_PATHCCH) && HAVE_PATHCCH + wchar_t *pathw = mp_from_utf8(NULL, path); + wchar_t *read = pathw, *write = pathw; + wchar_t prev = '\0'; + // preserve leading double backslashes + if (read[0] == '\\' && read[1] == '\\') { + prev = '\\'; + write += 2; + read += 2; + } + wchar_t curr; + while ((curr = *read)) { + if (curr == '/') + curr = '\\'; + if (curr != '\\' || prev != '\\') + *write++ = curr; + prev = curr; + read++; + } + *write = '\0'; + size_t max_size = wcslen(pathw) + 1; + wchar_t *pathc = talloc_array(NULL, wchar_t, max_size); + HRESULT hr = PathCchCanonicalizeEx(pathc, max_size, pathw, PATHCCH_ALLOW_LONG_PATHS); + char *ret = SUCCEEDED(hr) ? mp_to_utf8(talloc_ctx, pathc) : talloc_strdup(talloc_ctx, path); + talloc_free(pathw); + talloc_free(pathc); + return ret; +#elif HAVE_DOS_PATHS + return talloc_strdup(talloc_ctx, path); +#else + char *result = talloc_strdup(talloc_ctx, ""); + const char *next; + const char *end = path + strlen(path); + + for (const char *ptr = path; ptr < end; ptr = next + 1) { + next = memchr(ptr, '/', end - ptr); + if (next == NULL) + next = end; + + switch (next - ptr) { + case 0: + continue; + case 1: + if (ptr[0] == '.') + continue; + break; + case 2: + // Normalizing symlink/.. results in a wrong path: if the + // current working directory is /tmp/foo, and it is a symlink to + // /usr/bin, mpv ../file.mkv opens /usr/file.mkv, so we can't + // normalize the path to /tmp/file.mkv. Resolve symlinks to fix + // this. Otherwise we don't use realpath so users can use + // symlinks e.g. to hide how media files are distributed over + // real storage and move them while still resuming playback as + // long as the symlinked path doesn't change. + if (ptr[0] == '.' && ptr[1] == '.') { + char *tmp_result = realpath(path, NULL); + result = talloc_strdup(talloc_ctx, tmp_result); + free(tmp_result); + return result; + } + } + + result = talloc_strdup_append_buffer(result, "/"); + result = talloc_strndup_append_buffer(result, ptr, next - ptr); + } + + return result; +#endif } bool mp_path_exists(const char *path) diff --git a/misc/thread_tools.c b/misc/thread_tools.c index 0f7fe8f77a..7a9303c727 100644 --- a/misc/thread_tools.c +++ b/misc/thread_tools.c @@ -18,9 +18,8 @@ #include <stdatomic.h> #include <string.h> #include <sys/types.h> -#include <unistd.h> -#ifdef __MINGW32__ +#ifdef _WIN32 #include <windows.h> #else #include <poll.h> @@ -261,7 +260,7 @@ int mp_cancel_get_fd(struct mp_cancel *c) return c->wakeup_pipe[0]; } -#ifdef __MINGW32__ +#ifdef _WIN32 void *mp_cancel_get_event(struct mp_cancel *c) { mp_mutex_lock(&c->lock); |