emulators/duckstation: Update to 20231209
This commit is contained in:
parent
bb1fceffe1
commit
d6b2071723
8 changed files with 6 additions and 553 deletions
|
@ -1,7 +1,6 @@
|
|||
PORTNAME= duckstation
|
||||
PORTVERSION= 20231124
|
||||
PORTVERSION= 20231209
|
||||
DISTVERSIONPREFIX= v
|
||||
PORTREVISION= 1
|
||||
CATEGORIES= emulators
|
||||
|
||||
MAINTAINER= martymac@FreeBSD.org
|
||||
|
@ -28,7 +27,7 @@ USES= cmake compiler:c++20-lang gl pkgconfig qt:6 sdl xorg
|
|||
USE_GITHUB= yes
|
||||
GH_ACCOUNT= stenzek
|
||||
# See: https://github.com/stenzek/duckstation/commits/latest
|
||||
GH_TAGNAME= 2739794
|
||||
GH_TAGNAME= a9ee2a3
|
||||
|
||||
USE_GL= egl
|
||||
USE_SDL= sdl2
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
TIMESTAMP = 1701196143
|
||||
SHA256 (stenzek-duckstation-v20231124-2739794_GH0.tar.gz) = 19aeb00b3e56f5c34bccc6829b85141e47742d7c9314de6141c909c91d921542
|
||||
SIZE (stenzek-duckstation-v20231124-2739794_GH0.tar.gz) = 13558980
|
||||
TIMESTAMP = 1702583549
|
||||
SHA256 (stenzek-duckstation-v20231209-a9ee2a3_GH0.tar.gz) = 610605653748f30769beeb0aed3ec4f732220020f21ba25243a476f359305e39
|
||||
SIZE (stenzek-duckstation-v20231209-a9ee2a3_GH0.tar.gz) = 13678691
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
Backport 407049c from upstream
|
||||
|
||||
commit 407049cd91b65c8a917533b87c7264dba3e2adc5
|
||||
Author: Stenzek <stenzek@gmail.com>
|
||||
Date: Tue Dec 5 15:21:52 2023 +1000
|
||||
|
||||
Qt: Resolve any symbolic links in AppRoot/DataRoot
|
||||
|
||||
Should fix incorrect relative path generation on FreeBSD, where /home is
|
||||
a symlink to /usr/home.
|
||||
|
||||
diff --git a/src/duckstation-nogui/nogui_host.cpp b/src/duckstation-nogui/nogui_host.cpp
|
||||
index 8e2778ed..15ce8ae5 100644
|
||||
--- src/duckstation-nogui/nogui_host.cpp
|
||||
+++ src/duckstation-nogui/nogui_host.cpp
|
||||
@@ -147,7 +147,7 @@ bool NoGUIHost::ShouldUsePortableMode()
|
||||
|
||||
void NoGUIHost::SetAppRoot()
|
||||
{
|
||||
- std::string program_path(FileSystem::GetProgramPath());
|
||||
+ const std::string program_path = FileSystem::GetProgramPath();
|
||||
Log_InfoPrintf("Program Path: %s", program_path.c_str());
|
||||
|
||||
EmuFolders::AppRoot = Path::Canonicalize(Path::GetDirectory(program_path));
|
||||
@@ -190,7 +190,7 @@ void NoGUIHost::SetDataDirectory()
|
||||
const char* xdg_config_home = getenv("XDG_CONFIG_HOME");
|
||||
if (xdg_config_home && Path::IsAbsolute(xdg_config_home))
|
||||
{
|
||||
- EmuFolders::DataRoot = Path::Combine(xdg_config_home, "duckstation");
|
||||
+ EmuFolders::DataRoot = Path::RealPath(Path::Combine(xdg_config_home, "duckstation"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -203,14 +203,14 @@ void NoGUIHost::SetDataDirectory()
|
||||
const std::string share_dir(Path::Combine(local_dir, "share"));
|
||||
FileSystem::EnsureDirectoryExists(local_dir.c_str(), false);
|
||||
FileSystem::EnsureDirectoryExists(share_dir.c_str(), false);
|
||||
- EmuFolders::DataRoot = Path::Combine(share_dir, "duckstation");
|
||||
+ EmuFolders::DataRoot = Path::RealPath(Path::Combine(share_dir, "duckstation"));
|
||||
}
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
static constexpr char MAC_DATA_DIR[] = "Library/Application Support/DuckStation";
|
||||
const char* home_dir = getenv("HOME");
|
||||
if (home_dir)
|
||||
- EmuFolders::DataRoot = Path::Combine(home_dir, MAC_DATA_DIR);
|
||||
+ EmuFolders::DataRoot = Path::RealPath(Path::Combine(home_dir, MAC_DATA_DIR));
|
||||
#endif
|
||||
|
||||
// make sure it exists
|
||||
diff --git a/src/duckstation-qt/qthost.cpp b/src/duckstation-qt/qthost.cpp
|
||||
index b7977cb6..9a52689c 100644
|
||||
--- src/duckstation-qt/qthost.cpp
|
||||
+++ src/duckstation-qt/qthost.cpp
|
||||
@@ -252,7 +252,7 @@ bool QtHost::ShouldUsePortableMode()
|
||||
|
||||
void QtHost::SetAppRoot()
|
||||
{
|
||||
- std::string program_path(FileSystem::GetProgramPath());
|
||||
+ const std::string program_path = FileSystem::GetProgramPath();
|
||||
Log_InfoPrintf("Program Path: %s", program_path.c_str());
|
||||
|
||||
EmuFolders::AppRoot = Path::Canonicalize(Path::GetDirectory(program_path));
|
||||
@@ -295,7 +295,7 @@ void QtHost::SetDataDirectory()
|
||||
const char* xdg_config_home = getenv("XDG_CONFIG_HOME");
|
||||
if (xdg_config_home && Path::IsAbsolute(xdg_config_home))
|
||||
{
|
||||
- EmuFolders::DataRoot = Path::Combine(xdg_config_home, "duckstation");
|
||||
+ EmuFolders::DataRoot = Path::RealPath(Path::Combine(xdg_config_home, "duckstation"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -308,14 +308,14 @@ void QtHost::SetDataDirectory()
|
||||
const std::string share_dir(Path::Combine(local_dir, "share"));
|
||||
FileSystem::EnsureDirectoryExists(local_dir.c_str(), false);
|
||||
FileSystem::EnsureDirectoryExists(share_dir.c_str(), false);
|
||||
- EmuFolders::DataRoot = Path::Combine(share_dir, "duckstation");
|
||||
+ EmuFolders::DataRoot = Path::RealPath(Path::Combine(share_dir, "duckstation"));
|
||||
}
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
static constexpr char MAC_DATA_DIR[] = "Library/Application Support/DuckStation";
|
||||
const char* home_dir = getenv("HOME");
|
||||
if (home_dir)
|
||||
- EmuFolders::DataRoot = Path::Combine(home_dir, MAC_DATA_DIR);
|
||||
+ EmuFolders::DataRoot = Path::RealPath(Path::Combine(home_dir, MAC_DATA_DIR));
|
||||
#endif
|
||||
|
||||
// make sure it exists
|
|
@ -1,369 +0,0 @@
|
|||
Backport 5246252 from upstream
|
||||
|
||||
commit 524625269fe5f365a10dbfc2e18c325b6c4fab61
|
||||
Author: Stenzek <stenzek@gmail.com>
|
||||
Date: Tue Dec 5 15:21:37 2023 +1000
|
||||
|
||||
Path: Add RealPath()
|
||||
|
||||
diff --git a/src/common-tests/path_tests.cpp b/src/common-tests/path_tests.cpp
|
||||
index c0e58526..03b307e4 100644
|
||||
--- src/common-tests/path_tests.cpp
|
||||
+++ src/common-tests/path_tests.cpp
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "common/types.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
-TEST(FileSystem, ToNativePath)
|
||||
+TEST(Path, ToNativePath)
|
||||
{
|
||||
ASSERT_EQ(Path::ToNativePath(""), "");
|
||||
|
||||
@@ -29,7 +29,7 @@ TEST(FileSystem, ToNativePath)
|
||||
#endif
|
||||
}
|
||||
|
||||
-TEST(FileSystem, IsAbsolute)
|
||||
+TEST(Path, IsAbsolute)
|
||||
{
|
||||
ASSERT_FALSE(Path::IsAbsolute(""));
|
||||
ASSERT_FALSE(Path::IsAbsolute("foo"));
|
||||
@@ -61,7 +61,7 @@ TEST(FileSystem, IsAbsolute)
|
||||
#endif
|
||||
}
|
||||
|
||||
-TEST(FileSystem, Canonicalize)
|
||||
+TEST(Path, Canonicalize)
|
||||
{
|
||||
ASSERT_EQ(Path::Canonicalize(""), Path::ToNativePath(""));
|
||||
ASSERT_EQ(Path::Canonicalize("foo/bar/../baz"), Path::ToNativePath("foo/baz"));
|
||||
@@ -72,10 +72,8 @@ TEST(FileSystem, Canonicalize)
|
||||
ASSERT_EQ(Path::Canonicalize("./foo"), Path::ToNativePath("foo"));
|
||||
ASSERT_EQ(Path::Canonicalize("../foo"), Path::ToNativePath("../foo"));
|
||||
ASSERT_EQ(Path::Canonicalize("foo/b🙃ar/../b🙃az/./foo"), Path::ToNativePath("foo/b🙃az/foo"));
|
||||
- ASSERT_EQ(
|
||||
- Path::Canonicalize(
|
||||
- "ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤℹ︎∩₲ ₱⟑♰⫳🐱/b🙃az/../foℹ︎o"),
|
||||
- Path::ToNativePath("ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤℹ︎∩₲ ₱⟑♰⫳🐱/foℹ︎o"));
|
||||
+ ASSERT_EQ(Path::Canonicalize("ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤℹ︎∩₲ ₱⟑♰⫳🐱/b🙃az/../foℹ︎o"),
|
||||
+ Path::ToNativePath("ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤℹ︎∩₲ ₱⟑♰⫳🐱/foℹ︎o"));
|
||||
#ifdef _WIN32
|
||||
ASSERT_EQ(Path::Canonicalize("C:\\foo\\bar\\..\\baz\\.\\foo"), "C:\\foo\\baz\\foo");
|
||||
ASSERT_EQ(Path::Canonicalize("C:/foo\\bar\\..\\baz\\.\\foo"), "C:\\foo\\baz\\foo");
|
||||
@@ -87,7 +85,7 @@ TEST(FileSystem, Canonicalize)
|
||||
#endif
|
||||
}
|
||||
|
||||
-TEST(FileSystem, Combine)
|
||||
+TEST(Path, Combine)
|
||||
{
|
||||
ASSERT_EQ(Path::Combine("", ""), Path::ToNativePath(""));
|
||||
ASSERT_EQ(Path::Combine("foo", "bar"), Path::ToNativePath("foo/bar"));
|
||||
@@ -108,7 +106,7 @@ TEST(FileSystem, Combine)
|
||||
#endif
|
||||
}
|
||||
|
||||
-TEST(FileSystem, AppendDirectory)
|
||||
+TEST(Path, AppendDirectory)
|
||||
{
|
||||
ASSERT_EQ(Path::AppendDirectory("foo/bar", "baz"), Path::ToNativePath("foo/baz/bar"));
|
||||
ASSERT_EQ(Path::AppendDirectory("", "baz"), Path::ToNativePath("baz"));
|
||||
@@ -122,7 +120,7 @@ TEST(FileSystem, AppendDirectory)
|
||||
#endif
|
||||
}
|
||||
|
||||
-TEST(FileSystem, MakeRelative)
|
||||
+TEST(Path, MakeRelative)
|
||||
{
|
||||
ASSERT_EQ(Path::MakeRelative("", ""), Path::ToNativePath(""));
|
||||
ASSERT_EQ(Path::MakeRelative("foo", ""), Path::ToNativePath("foo"));
|
||||
@@ -141,8 +139,7 @@ TEST(FileSystem, MakeRelative)
|
||||
ASSERT_EQ(Path::MakeRelative(A "foo/b🙃ar", A "foo/b🙃az"), Path::ToNativePath("../b🙃ar"));
|
||||
ASSERT_EQ(Path::MakeRelative(A "f🙃oo/b🙃ar", A "f🙃oo/b🙃az"), Path::ToNativePath("../b🙃ar"));
|
||||
ASSERT_EQ(
|
||||
- Path::MakeRelative(A "ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤℹ︎∩₲ ₱⟑♰⫳🐱/b🙃ar",
|
||||
- A "ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤℹ︎∩₲ ₱⟑♰⫳🐱/b🙃az"),
|
||||
+ Path::MakeRelative(A "ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤℹ︎∩₲ ₱⟑♰⫳🐱/b🙃ar", A "ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤℹ︎∩₲ ₱⟑♰⫳🐱/b🙃az"),
|
||||
Path::ToNativePath("../b🙃ar"));
|
||||
|
||||
#undef A
|
||||
@@ -154,7 +151,7 @@ TEST(FileSystem, MakeRelative)
|
||||
#endif
|
||||
}
|
||||
|
||||
-TEST(FileSystem, GetExtension)
|
||||
+TEST(Path, GetExtension)
|
||||
{
|
||||
ASSERT_EQ(Path::GetExtension("foo"), "");
|
||||
ASSERT_EQ(Path::GetExtension("foo.txt"), "txt");
|
||||
@@ -164,7 +161,7 @@ TEST(FileSystem, GetExtension)
|
||||
ASSERT_EQ(Path::GetExtension("a/b/foo"), "");
|
||||
}
|
||||
|
||||
-TEST(FileSystem, GetFileName)
|
||||
+TEST(Path, GetFileName)
|
||||
{
|
||||
ASSERT_EQ(Path::GetFileName(""), "");
|
||||
ASSERT_EQ(Path::GetFileName("foo"), "foo");
|
||||
@@ -179,7 +176,7 @@ TEST(FileSystem, GetFileName)
|
||||
#endif
|
||||
}
|
||||
|
||||
-TEST(FileSystem, GetFileTitle)
|
||||
+TEST(Path, GetFileTitle)
|
||||
{
|
||||
ASSERT_EQ(Path::GetFileTitle(""), "");
|
||||
ASSERT_EQ(Path::GetFileTitle("foo"), "foo");
|
||||
@@ -193,7 +190,7 @@ TEST(FileSystem, GetFileTitle)
|
||||
#endif
|
||||
}
|
||||
|
||||
-TEST(FileSystem, GetDirectory)
|
||||
+TEST(Path, GetDirectory)
|
||||
{
|
||||
ASSERT_EQ(Path::GetDirectory(""), "");
|
||||
ASSERT_EQ(Path::GetDirectory("foo"), "");
|
||||
@@ -207,7 +204,7 @@ TEST(FileSystem, GetDirectory)
|
||||
#endif
|
||||
}
|
||||
|
||||
-TEST(FileSystem, ChangeFileName)
|
||||
+TEST(Path, ChangeFileName)
|
||||
{
|
||||
ASSERT_EQ(Path::ChangeFileName("", ""), Path::ToNativePath(""));
|
||||
ASSERT_EQ(Path::ChangeFileName("", "bar"), Path::ToNativePath("bar"));
|
||||
@@ -227,13 +224,14 @@ TEST(FileSystem, ChangeFileName)
|
||||
#endif
|
||||
}
|
||||
|
||||
-TEST(FileSystem, SanitizeFileName)
|
||||
+TEST(Path, SanitizeFileName)
|
||||
{
|
||||
ASSERT_EQ(Path::SanitizeFileName("foo"), "foo");
|
||||
ASSERT_EQ(Path::SanitizeFileName("foo/bar"), "foo_bar");
|
||||
ASSERT_EQ(Path::SanitizeFileName("f🙃o"), "f🙃o");
|
||||
ASSERT_EQ(Path::SanitizeFileName("ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤℹ︎∩₲ ₱⟑♰⫳🐱"), "ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤℹ︎∩₲ ₱⟑♰⫳🐱");
|
||||
- ASSERT_EQ(Path::SanitizeFileName("abcdefghijlkmnopqrstuvwxyz-0123456789+&=_[]{}"), "abcdefghijlkmnopqrstuvwxyz-0123456789+&=_[]{}");
|
||||
+ ASSERT_EQ(Path::SanitizeFileName("abcdefghijlkmnopqrstuvwxyz-0123456789+&=_[]{}"),
|
||||
+ "abcdefghijlkmnopqrstuvwxyz-0123456789+&=_[]{}");
|
||||
ASSERT_EQ(Path::SanitizeFileName("some*path**with*asterisks"), "some_path__with_asterisks");
|
||||
#ifdef _WIN32
|
||||
ASSERT_EQ(Path::SanitizeFileName("foo:"), "foo_");
|
||||
@@ -243,4 +241,18 @@ TEST(FileSystem, SanitizeFileName)
|
||||
ASSERT_EQ(Path::SanitizeFileName("foo\\bar", false), "foo\\bar");
|
||||
#endif
|
||||
ASSERT_EQ(Path::SanitizeFileName("foo/bar", false), "foo/bar");
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+}
|
||||
+
|
||||
+#if 0
|
||||
+
|
||||
+// Relies on presence of files.
|
||||
+TEST(Path, RealPath)
|
||||
+{
|
||||
+#ifdef _WIN32
|
||||
+ ASSERT_EQ(Path::RealPath("C:\\Users\\Me\\Desktop\\foo\\baz"), "C:\\Users\\Me\\Desktop\\foo\\bar\\baz");
|
||||
+#else
|
||||
+ ASSERT_EQ(Path::RealPath("/lib/foo/bar"), "/usr/lib/foo/bar");
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
\ No newline at end of file
|
||||
diff --git a/src/common/file_system.cpp b/src/common/file_system.cpp
|
||||
index 4a5fc6b0..4ce4b9ed 100644
|
||||
--- src/common/file_system.cpp
|
||||
+++ src/common/file_system.cpp
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
+#include <numeric>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach-o/dyld.h>
|
||||
@@ -192,6 +193,161 @@ bool Path::IsAbsolute(const std::string_view& path)
|
||||
#endif
|
||||
}
|
||||
|
||||
+std::string Path::RealPath(const std::string_view& path)
|
||||
+{
|
||||
+ // Resolve non-absolute paths first.
|
||||
+ std::vector<std::string_view> components;
|
||||
+ if (!IsAbsolute(path))
|
||||
+ components = Path::SplitNativePath(Path::Combine(FileSystem::GetWorkingDirectory(), path));
|
||||
+ else
|
||||
+ components = Path::SplitNativePath(path);
|
||||
+
|
||||
+ std::string realpath;
|
||||
+ if (components.empty())
|
||||
+ return realpath;
|
||||
+
|
||||
+ // Different to path because relative.
|
||||
+ realpath.reserve(std::accumulate(components.begin(), components.end(), static_cast<size_t>(0),
|
||||
+ [](size_t l, const std::string_view& s) { return l + s.length(); }) +
|
||||
+ components.size() + 1);
|
||||
+
|
||||
+#ifdef _WIN32
|
||||
+ std::wstring wrealpath;
|
||||
+ std::vector<WCHAR> symlink_buf;
|
||||
+ wrealpath.reserve(realpath.size());
|
||||
+ symlink_buf.resize(path.size() + 1);
|
||||
+
|
||||
+ // Check for any symbolic links throughout the path while adding components.
|
||||
+ bool test_symlink = true;
|
||||
+ for (const std::string_view& comp : components)
|
||||
+ {
|
||||
+ if (!realpath.empty())
|
||||
+ realpath.push_back(FS_OSPATH_SEPARATOR_CHARACTER);
|
||||
+ realpath.append(comp);
|
||||
+ if (test_symlink)
|
||||
+ {
|
||||
+ DWORD attribs;
|
||||
+ if (StringUtil::UTF8StringToWideString(wrealpath, realpath) &&
|
||||
+ (attribs = GetFileAttributesW(wrealpath.c_str())) != INVALID_FILE_ATTRIBUTES)
|
||||
+ {
|
||||
+ // if not a link, go to the next component
|
||||
+ if (attribs & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
+ {
|
||||
+ const HANDLE hFile =
|
||||
+ CreateFileW(wrealpath.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
+ nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
|
||||
+ if (hFile != INVALID_HANDLE_VALUE)
|
||||
+ {
|
||||
+ // is a link! resolve it.
|
||||
+ DWORD ret = GetFinalPathNameByHandleW(hFile, symlink_buf.data(), static_cast<DWORD>(symlink_buf.size()),
|
||||
+ FILE_NAME_NORMALIZED);
|
||||
+ if (ret > symlink_buf.size())
|
||||
+ {
|
||||
+ symlink_buf.resize(ret);
|
||||
+ ret = GetFinalPathNameByHandleW(hFile, symlink_buf.data(), static_cast<DWORD>(symlink_buf.size()),
|
||||
+ FILE_NAME_NORMALIZED);
|
||||
+ }
|
||||
+ if (ret != 0)
|
||||
+ StringUtil::WideStringToUTF8String(realpath, std::wstring_view(symlink_buf.data(), ret));
|
||||
+ else
|
||||
+ test_symlink = false;
|
||||
+
|
||||
+ CloseHandle(hFile);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ // not a file or link
|
||||
+ test_symlink = false;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // GetFinalPathNameByHandleW() adds a \\?\ prefix, so remove it.
|
||||
+ if (realpath.starts_with("\\\\?\\") && IsAbsolute(std::string_view(realpath.data() + 4, realpath.size() - 4)))
|
||||
+ realpath.erase(0, 4);
|
||||
+
|
||||
+#else
|
||||
+ // Why this monstrosity instead of calling realpath()? realpath() only works on files that exist.
|
||||
+ std::string basepath;
|
||||
+ std::string symlink;
|
||||
+
|
||||
+ basepath.reserve(realpath.capacity());
|
||||
+ symlink.resize(realpath.capacity());
|
||||
+
|
||||
+ // Check for any symbolic links throughout the path while adding components.
|
||||
+ bool test_symlink = true;
|
||||
+ for (const std::string_view& comp : components)
|
||||
+ {
|
||||
+ if (!test_symlink)
|
||||
+ {
|
||||
+ realpath.push_back(FS_OSPATH_SEPARATOR_CHARACTER);
|
||||
+ realpath.append(comp);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ basepath = realpath;
|
||||
+ if (realpath.empty() || realpath.back() != FS_OSPATH_SEPARATOR_CHARACTER)
|
||||
+ realpath.push_back(FS_OSPATH_SEPARATOR_CHARACTER);
|
||||
+ realpath.append(comp);
|
||||
+
|
||||
+ // Check if the last component added is a symlink
|
||||
+ struct stat sb;
|
||||
+ if (lstat(realpath.c_str(), &sb) != 0)
|
||||
+ {
|
||||
+ // Don't bother checking any further components once we error out.
|
||||
+ test_symlink = false;
|
||||
+ continue;
|
||||
+ }
|
||||
+ else if (!S_ISLNK(sb.st_mode))
|
||||
+ {
|
||||
+ // Nope, keep going.
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ ssize_t sz = readlink(realpath.c_str(), symlink.data(), symlink.size());
|
||||
+ if (sz < 0)
|
||||
+ {
|
||||
+ // shouldn't happen, due to the S_ISLNK check above.
|
||||
+ test_symlink = false;
|
||||
+ break;
|
||||
+ }
|
||||
+ else if (static_cast<size_t>(sz) == symlink.size())
|
||||
+ {
|
||||
+ // need a larger buffer
|
||||
+ symlink.resize(symlink.size() * 2);
|
||||
+ continue;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ // is a link, and we resolved it. gotta check if the symlink itself is relative :(
|
||||
+ symlink.resize(static_cast<size_t>(sz));
|
||||
+ if (!Path::IsAbsolute(symlink))
|
||||
+ {
|
||||
+ // symlink is relative to the directory of the symlink
|
||||
+ realpath = basepath;
|
||||
+ if (realpath.empty() || realpath.back() != FS_OSPATH_SEPARATOR_CHARACTER)
|
||||
+ realpath.push_back(FS_OSPATH_SEPARATOR_CHARACTER);
|
||||
+ realpath.append(symlink);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ // Use the new, symlinked path.
|
||||
+ realpath = symlink;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ return realpath;
|
||||
+}
|
||||
+
|
||||
std::string Path::ToNativePath(const std::string_view& path)
|
||||
{
|
||||
std::string ret;
|
||||
@@ -1382,6 +1538,7 @@ std::string FileSystem::GetProgramPath()
|
||||
break;
|
||||
}
|
||||
|
||||
+ // Windows symlinks don't behave silly like Linux, so no need to RealPath() it.
|
||||
return StringUtil::WideStringToUTF8String(buffer);
|
||||
}
|
||||
|
||||
diff --git a/src/common/path.h b/src/common/path.h
|
||||
index 7c03c1ad..12d86471 100644
|
||||
--- src/common/path.h
|
||||
+++ src/common/path.h
|
||||
@@ -31,6 +31,9 @@ void SanitizeFileName(std::string* str, bool strip_slashes = true);
|
||||
/// Returns true if the specified path is an absolute path (C:\Path on Windows or /path on Unix).
|
||||
bool IsAbsolute(const std::string_view& path);
|
||||
|
||||
+/// Resolves any symbolic links in the specified path.
|
||||
+std::string RealPath(const std::string_view& path);
|
||||
+
|
||||
/// Makes the specified path relative to another (e.g. /a/b/c, /a/b -> ../c).
|
||||
/// Both paths must be relative, otherwise this function will just return the input path.
|
||||
std::string MakeRelative(const std::string_view& path, const std::string_view& relative_to);
|
|
@ -1,30 +0,0 @@
|
|||
Backport 5486a7a from upstream
|
||||
|
||||
commit 5486a7a467dc0cd502bd8c4e7eb7a3c95a5a3c02
|
||||
Author: Ganael Laplanche <ganael.laplanche@martymac.org>
|
||||
Date: Wed Nov 29 21:05:21 2023 +0100
|
||||
|
||||
Fix get_thread_time() declaration on FreeBSD
|
||||
|
||||
diff --git a/src/common/threading.cpp b/src/common/threading.cpp
|
||||
index ac272ff1..8dacce83 100644
|
||||
--- src/common/threading.cpp
|
||||
+++ src/common/threading.cpp
|
||||
@@ -64,7 +64,7 @@ static u64 getthreadtime(thread_port_t thread)
|
||||
}
|
||||
#endif
|
||||
|
||||
-#ifdef __linux__
|
||||
+#if defined(__linux__) || defined(__FreeBSD__)
|
||||
// Helper function to get either either the current cpu usage
|
||||
// in called thread or in id thread
|
||||
static u64 get_thread_time(void* id = 0)
|
||||
@@ -227,7 +227,7 @@ u64 Threading::ThreadHandle::GetCPUTime() const
|
||||
return user.u64time + kernel.u64time;
|
||||
#elif defined(__APPLE__)
|
||||
return getthreadtime(pthread_mach_thread_np((pthread_t)m_native_handle));
|
||||
-#elif defined(__linux__)
|
||||
+#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
return get_thread_time(m_native_handle);
|
||||
#else
|
||||
return 0;
|
|
@ -1,25 +0,0 @@
|
|||
Backport af046c8 from upstream
|
||||
|
||||
commit af046c8987ec3c580eff8a0c7c438762377fdbca
|
||||
Author: Ganael Laplanche <ganael.laplanche@martymac.org>
|
||||
Date: Wed Nov 29 20:54:12 2023 +0100
|
||||
|
||||
Fix build on FreeBSD
|
||||
|
||||
FreeBSD's alloca(3) only needs <stdlib.h>
|
||||
|
||||
diff --git a/src/common/byte_stream.cpp b/src/common/byte_stream.cpp
|
||||
index bb26af0f..18609996 100644
|
||||
--- src/common/byte_stream.cpp
|
||||
+++ src/common/byte_stream.cpp
|
||||
@@ -28,8 +28,10 @@
|
||||
#ifdef _MSC_VER
|
||||
#include <malloc.h>
|
||||
#else
|
||||
+#if !defined(__FreeBSD__)
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
+#endif
|
||||
|
||||
Log_SetChannel(ByteStream);
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
Backport b6d6756 from upstream
|
||||
|
||||
commit b6d67560e39ca3c7154d97355fec988210a460e5
|
||||
Author: Ganael Laplanche <ganael.laplanche@martymac.org>
|
||||
Date: Wed Nov 29 20:38:56 2023 +0100
|
||||
|
||||
Fix data directory handling on FreeBSD
|
||||
|
||||
diff --git a/src/duckstation-nogui/nogui_host.cpp b/src/duckstation-nogui/nogui_host.cpp
|
||||
index 5543c2c9..8e2778ed 100644
|
||||
--- src/duckstation-nogui/nogui_host.cpp
|
||||
+++ src/duckstation-nogui/nogui_host.cpp
|
||||
@@ -185,7 +185,7 @@ void NoGUIHost::SetDataDirectory()
|
||||
EmuFolders::DataRoot = Path::Combine(StringUtil::WideStringToUTF8String(documents_directory), "DuckStation");
|
||||
CoTaskMemFree(documents_directory);
|
||||
}
|
||||
-#elif defined(__linux__)
|
||||
+#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
// Use $XDG_CONFIG_HOME/duckstation if it exists.
|
||||
const char* xdg_config_home = getenv("XDG_CONFIG_HOME");
|
||||
if (xdg_config_home && Path::IsAbsolute(xdg_config_home))
|
||||
diff --git a/src/duckstation-qt/qthost.cpp b/src/duckstation-qt/qthost.cpp
|
||||
index a2039160..b7977cb6 100644
|
||||
--- src/duckstation-qt/qthost.cpp
|
||||
+++ src/duckstation-qt/qthost.cpp
|
||||
@@ -290,7 +290,7 @@ void QtHost::SetDataDirectory()
|
||||
EmuFolders::DataRoot = Path::Combine(StringUtil::WideStringToUTF8String(documents_directory), "DuckStation");
|
||||
CoTaskMemFree(documents_directory);
|
||||
}
|
||||
-#elif defined(__linux__)
|
||||
+#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
// Use $XDG_CONFIG_HOME/duckstation if it exists.
|
||||
const char* xdg_config_home = getenv("XDG_CONFIG_HOME");
|
||||
if (xdg_config_home && Path::IsAbsolute(xdg_config_home))
|
|
@ -6,6 +6,7 @@ share/pixmaps/duckstation.png
|
|||
%%DATADIR%%/resources/fonts/Roboto-Regular.ttf
|
||||
%%DATADIR%%/resources/fonts/RobotoMono-Medium.ttf
|
||||
%%DATADIR%%/resources/fonts/fa-solid-900.ttf
|
||||
%%DATADIR%%/resources/fonts/promptfont.otf
|
||||
%%DATADIR%%/resources/fullscreenui/NTSC-J.png
|
||||
%%DATADIR%%/resources/fullscreenui/NTSC-U.png
|
||||
%%DATADIR%%/resources/fullscreenui/PAL.png
|
||||
|
|
Loading…
Reference in a new issue