From 0c395576eb4918b8c2b2a3eb95ac51fb5af5e5de Mon Sep 17 00:00:00 2001 From: MoHadiShibli <142665133+MoHadiShibli@users.noreply.github.com> Date: Mon, 5 Oct 2026 14:31:24 +0300 Subject: [PATCH] Launcher: refresh the status every 2 seconds, as it was meant to The app's controller count, and everything else on its screen, only changed when the app was closed and opened again. OpenOrbis's time.h gives CLOCK_MONOTONIC the Linux value, 1. The PS4's kernel is FreeBSD's, where clock 1 is CLOCK_VIRTUAL: the process's own CPU time. The worker sleeps between checks and uses almost none, so its clock barely moved and the check due 2 seconds later never came round. Only the first check, on start-up, ever ran. The payload is unaffected: its SDK has FreeBSD's value, 4. The launcher now uses 4 when it is built for the console. Checked the other constants the app uses against FreeBSD's: everything matches except this one, MSG_NOSIGNAL and SIGSYS, which were already worked around. A test now fails if any of the three is used directly in the launcher again. --- launcher/service.c | 13 ++++++++++++- tests/test_launcher.py | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/launcher/service.c b/launcher/service.c index 844475d..ae933fc 100644 --- a/launcher/service.c +++ b/launcher/service.c @@ -21,6 +21,17 @@ #define C4F_PAYLOADER_PORT 9090 #endif +/* OpenOrbis's time.h gives CLOCK_MONOTONIC the Linux value, 1. The PS4's kernel + * is FreeBSD's, and there 1 is CLOCK_VIRTUAL: this process's own CPU time, which + * an app that mostly sleeps hardly uses. The status check due every 2 seconds + * then never came round, and the screen kept its first reading until the app was + * reopened. 4 is FreeBSD's CLOCK_MONOTONIC, the value the payload's SDK uses. */ +#ifdef __FreeBSD__ +#define C4F_CLOCK_MONOTONIC 4 +#else +#define C4F_CLOCK_MONOTONIC CLOCK_MONOTONIC +#endif + static char c4fHost[16]; static char c4fProblem[128]; static int c4fReached; @@ -28,7 +39,7 @@ static int c4fReached; uint64_t c4fLauncherTimeMs(void) { struct timespec t; - clock_gettime(CLOCK_MONOTONIC, &t); + clock_gettime(C4F_CLOCK_MONOTONIC, &t); return (uint64_t)t.tv_sec * 1000 + t.tv_nsec / 1000000; } diff --git a/tests/test_launcher.py b/tests/test_launcher.py index 87fde64..a082924 100644 --- a/tests/test_launcher.py +++ b/tests/test_launcher.py @@ -2,6 +2,7 @@ import json import os from pathlib import Path +import re import socket import subprocess import sys @@ -177,6 +178,23 @@ def main(): assert fresh.read_bytes() == shipped.read_bytes(), f'{shipped} is out of date: run tools/make_icons.py' print('PASS native screen states and icon rendered from the shipped drawing code', flush=True) + # OpenOrbis's headers give a few constants their Linux values, and the PS4's + # FreeBSD kernel reads those as something else: MSG_NOSIGNAL (0x4000, not + # 0x20000), SIGSYS (31, not 12) and CLOCK_MONOTONIC (1, which is CLOCK_VIRTUAL, + # not 4). Each has broken the app on the console once. Only a C4F_ definition + # that translates one, a comment, or a Linux-only guard may name them. + trap = re.compile(r'\b(CLOCK_MONOTONIC|MSG_NOSIGNAL|SIGSYS)\b') + allowed = re.compile(r'^\s*(#define C4F_|/\*|\*|//)|__linux__') + found = [] + for source in sorted(list((ROOT / 'launcher').glob('*.c')) + list((ROOT / 'launcher').glob('*.cpp'))): + lines = source.read_text().splitlines() + for number, line in enumerate(lines, 1): + guarded = number > 1 and '__linux__' in lines[number - 2] + if trap.search(line) and not allowed.search(line) and not guarded: + found.append(f'{source.relative_to(ROOT)}:{number}: {line.strip()}') + assert not found, 'OpenOrbis Linux-valued constant used directly:\n' + '\n'.join(found) + print('PASS no OpenOrbis constant with a Linux value is used directly', flush=True) + if __name__ == '__main__': main()