From nobody Wed Dec 06 12:03:58 2023 X-Original-To: dev-commits-ports-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4SlbfQ6KFjz53Ltr; Wed, 6 Dec 2023 12:03:58 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4SlbfQ5wf4z3WtJ; Wed, 6 Dec 2023 12:03:58 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1701864238; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=8O6knFkh76vRME2yzaSzBazYGjke9qI0YFp4aMcjdS0=; b=C16ffj40TgELlGzBXqUdYH1NvyfGrn1sAFgU1LsA0nF1pqHKJWholU61qLgpoduKOughOb zNNAQolxmpyFcE4rYkPbwJbTnjx6qUEolH+NxIlKO5KUBi8bnwvuSik51cmqNrdEOmCJ0H 78Nn8fFKzsJROonIO7YA07hhm0G51ga3XUfrSJbCNu+BIIT7vZD70fqa5Y7m2M213ON8Ed mN12HcUQVXX2KQO97dpAMu/oONLcZqkPViawc7qseAFYnm7+pf8jDYRk/3RI/KLyjWl1wU zNEeqUp0dsewKKssfyQR5ZVZWSDnBDE9vXB0wuVlcSDsPShevCerN4/lnsmylg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1701864238; a=rsa-sha256; cv=none; b=CdaqyxvsupbHgOxPZKspMpts5LH72cd3rfS/xaLsehE8FuPPvVKUBQbm7j4F5C/VJIda1P P8YMIqd4QppilUGnPdl7W49kMRjJF1MF6SAA+PNbA5oY7DkdnHrjIPqiBjahfLK6/KkUgw JpPfyW7GtSIrqBIINPXHHN974o//K1I1Ji8agu2EDVx0U578CcqmaoFPLdtRjPIYTNL6/z ZbyBS8TIiUfZnLt1ctK7oEjFTMU/h3Uw+/uIwaAiZol4xaV7DdsJuvzLAIWifSagtthjv5 7V5RmVzP37dT+mDwXviUJenRWXa0w2rbREjuqYtvDE2JJ/XTNzBA8WpNLDWGTQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1701864238; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=8O6knFkh76vRME2yzaSzBazYGjke9qI0YFp4aMcjdS0=; b=FK/fQUel4E9EqiRFWpUFH5SuHgb5t3Z5Csg4tboqkQql+XBR+2+7Ii5RPxdgNmPEzAK2I/ ayialnXMkR70/ZlaPM69vO1wVRxCAPmhOunQ15oufbm8/CIROHdCTJrCQtqpQCHfiM+HNO b3QQR5jJPMHVOn16b8o75RdrYcgBA80t6K95WAh3pW3/pQvtmu5ozpEQRjwxIvv82Jkkmw z/rnpI/yiOdwU+anq96xlGYRS0cqTKR0QdV4edH+sGohs80gKZuD6s5CKs/K2OtzQIIOTA nNIc3Hen93kooTjQbrQPpHi/jAykaRVeUr0sHSpzuIdHB2e0Qe6GmfOikWp+Ww== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4SlbfQ4xdszrp2; Wed, 6 Dec 2023 12:03:58 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 3B6C3wI6083096; Wed, 6 Dec 2023 12:03:58 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3B6C3wGa083093; Wed, 6 Dec 2023 12:03:58 GMT (envelope-from git) Date: Wed, 6 Dec 2023 12:03:58 GMT Message-Id: <202312061203.3B6C3wGa083093@gitrepo.freebsd.org> To: ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org From: Ganael LAPLANCHE Subject: git: 79dc32d40ec0 - main - emulators/duckstation: Update patches following upstream integration List-Id: Commit messages for all branches of the ports repository List-Archive: https://lists.freebsd.org/archives/dev-commits-ports-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-ports-all@freebsd.org X-BeenThere: dev-commits-ports-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: martymac X-Git-Repository: ports X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 79dc32d40ec08b1fb6326805db934e351e0e524b Auto-Submitted: auto-generated The branch main has been updated by martymac: URL: https://cgit.FreeBSD.org/ports/commit/?id=79dc32d40ec08b1fb6326805db934e351e0e524b commit 79dc32d40ec08b1fb6326805db934e351e0e524b Author: Ganael LAPLANCHE AuthorDate: 2023-12-06 11:38:22 +0000 Commit: Ganael LAPLANCHE CommitDate: 2023-12-06 12:03:25 +0000 emulators/duckstation: Update patches following upstream integration --- emulators/duckstation/Makefile | 1 + emulators/duckstation/files/patch-407049c.txt | 89 +++++ emulators/duckstation/files/patch-5246252.txt | 369 +++++++++++++++++++++ ...-src-common-threading.cpp => patch-5486a7a.txt} | 12 +- emulators/duckstation/files/patch-af046c8.txt | 25 ++ ...{patch-data-directory.txt => patch-b6d6756.txt} | 24 +- .../files/patch-src-common-byte_stream.cpp | 14 - .../files/patch-src-common-file_system.cpp | 70 ---- 8 files changed, 511 insertions(+), 93 deletions(-) diff --git a/emulators/duckstation/Makefile b/emulators/duckstation/Makefile index dc7ab1d7fc2f..0a7a09f50cbb 100644 --- a/emulators/duckstation/Makefile +++ b/emulators/duckstation/Makefile @@ -1,6 +1,7 @@ PORTNAME= duckstation PORTVERSION= 20231124 DISTVERSIONPREFIX= v +PORTREVISION= 1 CATEGORIES= emulators MAINTAINER= martymac@FreeBSD.org diff --git a/emulators/duckstation/files/patch-407049c.txt b/emulators/duckstation/files/patch-407049c.txt new file mode 100644 index 000000000000..d07843895516 --- /dev/null +++ b/emulators/duckstation/files/patch-407049c.txt @@ -0,0 +1,89 @@ +Backport 407049c from upstream + +commit 407049cd91b65c8a917533b87c7264dba3e2adc5 +Author: Stenzek +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 diff --git a/emulators/duckstation/files/patch-5246252.txt b/emulators/duckstation/files/patch-5246252.txt new file mode 100644 index 000000000000..35487f7939fa --- /dev/null +++ b/emulators/duckstation/files/patch-5246252.txt @@ -0,0 +1,369 @@ +Backport 5246252 from upstream + +commit 524625269fe5f365a10dbfc2e18c325b6c4fab61 +Author: Stenzek +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 + +-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 + #include + #include ++#include + + #ifdef __APPLE__ + #include +@@ -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 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(0), ++ [](size_t l, const std::string_view& s) { return l + s.length(); }) + ++ components.size() + 1); ++ ++#ifdef _WIN32 ++ std::wstring wrealpath; ++ std::vector 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(symlink_buf.size()), ++ FILE_NAME_NORMALIZED); ++ if (ret > symlink_buf.size()) ++ { ++ symlink_buf.resize(ret); ++ ret = GetFinalPathNameByHandleW(hFile, symlink_buf.data(), static_cast(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(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(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); diff --git a/emulators/duckstation/files/patch-src-common-threading.cpp b/emulators/duckstation/files/patch-5486a7a.txt similarity index 65% rename from emulators/duckstation/files/patch-src-common-threading.cpp rename to emulators/duckstation/files/patch-5486a7a.txt index 6448ee870fc0..f49e3f6f6af7 100644 --- a/emulators/duckstation/files/patch-src-common-threading.cpp +++ b/emulators/duckstation/files/patch-5486a7a.txt @@ -1,6 +1,14 @@ -Fix get_thread_time() declaration on FreeBSD +Backport 5486a7a from upstream ---- src/common/threading.cpp.orig 2023-10-16 12:57:57 UTC +commit 5486a7a467dc0cd502bd8c4e7eb7a3c95a5a3c02 +Author: Ganael Laplanche +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) } diff --git a/emulators/duckstation/files/patch-af046c8.txt b/emulators/duckstation/files/patch-af046c8.txt new file mode 100644 index 000000000000..1830dd4933d5 --- /dev/null +++ b/emulators/duckstation/files/patch-af046c8.txt @@ -0,0 +1,25 @@ +Backport af046c8 from upstream + +commit af046c8987ec3c580eff8a0c7c438762377fdbca +Author: Ganael Laplanche +Date: Wed Nov 29 20:54:12 2023 +0100 + + Fix build on FreeBSD + + FreeBSD's alloca(3) only needs + +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 + #else ++#if !defined(__FreeBSD__) + #include + #endif ++#endif + + Log_SetChannel(ByteStream); + diff --git a/emulators/duckstation/files/patch-data-directory.txt b/emulators/duckstation/files/patch-b6d6756.txt similarity index 58% rename from emulators/duckstation/files/patch-data-directory.txt rename to emulators/duckstation/files/patch-b6d6756.txt index 94f00c7aa01d..aa3be9286ef5 100644 --- a/emulators/duckstation/files/patch-data-directory.txt +++ b/emulators/duckstation/files/patch-b6d6756.txt @@ -1,8 +1,16 @@ -Fix data directory handling on FreeBSD +Backport b6d6756 from upstream ---- src/duckstation-qt/qthost.cpp.orig 2023-10-16 12:57:57 UTC -+++ src/duckstation-qt/qthost.cpp -@@ -289,7 +289,7 @@ void QtHost::SetDataDirectory() +commit b6d67560e39ca3c7154d97355fec988210a460e5 +Author: Ganael Laplanche +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); } @@ -11,9 +19,11 @@ Fix data directory handling on 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)) ---- src/duckstation-nogui/nogui_host.cpp.orig 2023-10-16 12:57:57 UTC -+++ src/duckstation-nogui/nogui_host.cpp -@@ -186,7 +186,7 @@ void NoGUIHost::SetDataDirectory() +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); } diff --git a/emulators/duckstation/files/patch-src-common-byte_stream.cpp b/emulators/duckstation/files/patch-src-common-byte_stream.cpp deleted file mode 100644 index f791bfdd6232..000000000000 --- a/emulators/duckstation/files/patch-src-common-byte_stream.cpp +++ /dev/null @@ -1,14 +0,0 @@ -FreeBSD's alloca(3) only needs - ---- src/common/byte_stream.cpp.orig 2023-10-16 12:57:57 UTC -+++ src/common/byte_stream.cpp -@@ -28,7 +28,9 @@ - #ifdef _MSC_VER - #include - #else -+#if !defined(__FreeBSD__) - #include -+#endif - #endif - - Log_SetChannel(ByteStream); diff --git a/emulators/duckstation/files/patch-src-common-file_system.cpp b/emulators/duckstation/files/patch-src-common-file_system.cpp deleted file mode 100644 index a88db23f479a..000000000000 --- a/emulators/duckstation/files/patch-src-common-file_system.cpp +++ /dev/null @@ -1,70 +0,0 @@ -Fix an off-by-one '..' error when computing bios SearchPath - -A '..' is missing in returned path when 'path' and 'relative_to' have no common -components. C++17's std::filesystem::relative() method returns a correct value. - -As an alternative to that simple patch, we may want to just replace -Path::MakeRelative() calls by std::filesystem::relative() calls and remove -Path::MakeRelative() method. - ---- src/common/file_system.cpp.orig 2023-10-16 12:57:57 UTC -+++ src/common/file_system.cpp -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - - #ifdef __APPLE__ - #include -@@ -250,49 +251,7 @@ std::string Path::MakeRelative(const std::string_view& - - std::string Path::MakeRelative(const std::string_view& path, const std::string_view& relative_to) - { -- // simple algorithm, we just work on the components. could probably be better, but it'll do for now. -- std::vector path_components(SplitNativePath(path)); -- std::vector relative_components(SplitNativePath(relative_to)); -- std::vector new_components; -- -- // both must be absolute paths -- if (Path::IsAbsolute(path) && Path::IsAbsolute(relative_to)) -- { -- // find the number of same components -- size_t num_same = 0; -- for (size_t i = 0; i < path_components.size() && i < relative_components.size(); i++) -- { -- if (path_components[i] == relative_components[i]) -- num_same++; -- else -- break; -- } -- -- // we need at least one same component -- if (num_same > 0) -- { -- // from the relative_to directory, back up to the start of the common components -- const size_t num_ups = relative_components.size() - num_same; -- for (size_t i = 0; i < num_ups; i++) -- new_components.emplace_back(".."); -- -- // and add the remainder of the path components -- for (size_t i = num_same; i < path_components.size(); i++) -- new_components.push_back(std::move(path_components[i])); -- } -- else -- { -- // no similarity -- new_components = std::move(path_components); -- } -- } -- else -- { -- // not absolute -- new_components = std::move(path_components); -- } -- -- return JoinNativePath(new_components); -+ return std::filesystem::relative(path, relative_to); - } - - std::string_view Path::GetExtension(const std::string_view& path)