summaryrefslogtreecommitdiffstats
path: root/misc
diff options
context:
space:
mode:
Diffstat (limited to 'misc')
-rw-r--r--misc/bstr.c1
-rw-r--r--misc/bstr.h2
-rw-r--r--misc/charset_conv.c4
-rw-r--r--misc/io_utils.c4
-rw-r--r--misc/language.c1
-rw-r--r--misc/path_utils.c87
-rw-r--r--misc/thread_tools.c5
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);