mirror of
https://github.com/mihawk-99/PS5_RetroArch.git
synced 2026-10-22 08:32:30 -05:00
The WebUI's new SMB page signs in to one server (guest or a user and password), lists its shares, checks a share and folder and saves them in config/smb.cfg on the console; the password is never answered back. RetroArch's file browser shows the share as SMB, after INTERNAL and EXTERNAL. smb:// paths go through RetroArch's VFS to src/ps5_smb_vfs.c (patches/series 0136), read-only and only on the saved server: a core that reads through the VFS streams the file, one that opens paths itself gets a copy in /app0/smb-cache, removed when the content closes. libsmb2 is pinned at the master revision itsPLK/ps5-pkg-manager runs on the PS5 (LGPL-2.1-or-later), built by tools/build-libsmb2.sh for the PS5 and the host and listed in tooling/notices/components.json: RetroArch 1.22.2 has no SMB client. In a title, getaddrinfo is bound to the platform layer's, which resolves nothing, so libsmb2's resolver calls go to RetroArch's own (src/platform_wraps.c); readv, writev, getlogin_r and getprotobyname are wrapped, so libsmb2 adds no import. SMB sockets set SO_NOSIGPIPE. Evidence: evidence/smb-load-content (python3 tools/evidence.py compare evidence/): on the Base PS5 the console's WebUI listed the PC's guest share and saved share/smb-test; Load Content > SMB listed it and a homebrew NES ROM on it ran under FCEUmm, read through the VFS (build a2c7800a, retroarch.log read back over FTP). Gates: tools/verify.sh (format, unit 214, build, integration, evidence 140) with PS5_REUSE_STAGED_CORES=ps5sx2: in this worktree the SDK's prospero-lld wrapper adds -pie to ps5sx2's link (clang passes its long object list in a response file the wrapper cannot read), so ps5sx2 is the main checkout's build of the same pinned revision. Host tests run a Samba server of their own (tests/smb_server.py, no root). Co-Authored-By: Claude <noreply@anthropic.com>
80 lines
3.8 KiB
Python
80 lines
3.8 KiB
Python
"""Native platform setup with isolated filesystem and menu-entry capture."""
|
|
from pathlib import Path
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
|
|
|
|
class PlatformPaths(unittest.TestCase):
|
|
def test_config_and_browser_roots(self):
|
|
with tempfile.TemporaryDirectory() as td:
|
|
binary = str(Path(td) / 'paths-test')
|
|
functions = ['fopen', 'stat', 'mkdir', 'chmod', 'rename', 'remove']
|
|
# The platform layer's headers, alone: the SDK's FreeBSD tree is
|
|
# not a host compiler's.
|
|
platform = Path(td) / 'platform-include'
|
|
platform.mkdir()
|
|
(platform / 'ps5platform').symlink_to(
|
|
ROOT / '.deps/native/ps5-payload-sdk/target/include/ps5platform')
|
|
# The SMB root's saved server (src/ps5_smb.c), read through the same fopen.
|
|
smb2 = subprocess.check_output(['bash', 'tools/build-libsmb2.sh', 'host'], cwd=ROOT,
|
|
text=True).strip()
|
|
smb = str(Path(td) / 'ps5_smb.o')
|
|
subprocess.run(['cc', '-std=c11', '-D_DEFAULT_SOURCE', '-O2', '-Wall', '-Werror', f'-I{smb2}/include',
|
|
'-c', 'src/ps5_smb.c', '-o', smb], cwd=ROOT, check=True)
|
|
subprocess.run(['c++', '-std=c++17', '-O2', '-Wall', '-Wextra', '-Werror',
|
|
'-Ivendor/retroarch', '-Ivendor/retroarch/libretro-common/include',
|
|
f'-I{platform}', '-Isrc',
|
|
'tests/frontend_ps5_test.cpp', smb, f'{smb2}/lib/libsmb2.a', '-lpthread', '-o', binary,
|
|
*[f'-Wl,--wrap={name}' for name in functions]], cwd=ROOT, check=True)
|
|
subprocess.run([binary, str(Path(td) / 'filesystem')], cwd=ROOT,
|
|
check=True, timeout=10)
|
|
|
|
def test_application_path_avoids_procfs(self):
|
|
import importlib.util
|
|
import re
|
|
spec = importlib.util.spec_from_file_location('patches', ROOT / 'tools/apply-port-patches.py')
|
|
patches = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(patches)
|
|
source = (ROOT / 'vendor/retroarch/libretro-common/file/file_path.c').read_text()
|
|
for path, anchor, replacement, marker in patches.EDITS:
|
|
if path == 'libretro-common/file/file_path.c' and marker not in source:
|
|
self.assertIn(anchor, source)
|
|
source = source.replace(anchor, replacement, 1)
|
|
body = re.search(r'size_t fill_pathname_application_path\(char \*s, size_t len\)\n\{.*?\n\}',
|
|
source, re.S)[0]
|
|
program = r'''
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
|
pid_t getpid(void) { abort(); }
|
|
ssize_t readlink(const char *p, char *b, size_t n) { abort(); }
|
|
size_t strlcpy(char *s, const char *p, size_t n) {
|
|
size_t len = strlen(p);
|
|
if (n) { size_t copied = len < n - 1 ? len : n - 1;
|
|
memcpy(s, p, copied); s[copied] = 0; }
|
|
return len;
|
|
}
|
|
''' + body + r'''
|
|
int main(void) {
|
|
char buffer[64];
|
|
assert(fill_pathname_application_path(buffer, sizeof(buffer)) == strlen("/app0/eboot.bin"));
|
|
assert(strcmp(buffer, "/app0/eboot.bin") == 0);
|
|
assert(fill_pathname_application_path(NULL, 0) == 0);
|
|
char small[4];
|
|
fill_pathname_application_path(small, sizeof(small));
|
|
assert(strcmp(small, "/ap") == 0);
|
|
}
|
|
'''
|
|
with tempfile.TemporaryDirectory() as td:
|
|
path = Path(td) / 'executable.c'
|
|
path.write_text(program)
|
|
binary = str(Path(td) / 'executable-test')
|
|
subprocess.run(['cc', '-std=gnu11', '-O2', str(path), '-o', binary], check=True)
|
|
subprocess.run([binary], check=True)
|