Commit Graph
107 Commits
Author SHA1 Message Date
MintMachineHQ c19c9ad47e fix(preflight): report a broken vulkaninfo, bound llvm-config and isolate tests
- an installed vulkaninfo that errors or times out is now a required failure
  with an actionable line; a missing one still only warns
- llvm_tools runs llvm-config with a 30 second timeout and reports it instead
  of hanging the preflight or the build
- RCLOL_PREFLIGHT_SOURCE overrides the prepared checkout, so the tests never
  scan (or fail on) a real build/darling-src

Adds four tests: missing vs broken vulkaninfo, and the two timeout paths.
2026-10-25 14:13:02 -06:00
MintMachineHQ fa18b2d04f feat(setup): check host versions before the build and the runtime install
setup failures reported in #137, #138 and #143 happened only after the long
fetch/build or at Riot startup. scripts/preflight.py now runs from
scripts/build.sh (before configure.py, so an old interpreter gets this message
and not a traceback) and from scripts/install-runtime.sh, and checks the host
once:

- python 3.10+, cmake 3.20+ (the bundled indium CMakeLists requires it),
  git-lfs 2.13+, kernel 5.14+ and LLVM 16+ exit nonzero with one actionable
  line each. RCLOL_SKIP_PREFLIGHT=1 bypasses the gate.
- llvm-objdump and llvm-nm are required, and unresolved names are explained.
- Vulkan 1.3 and timeline semaphores are required when vulkaninfo is
  installed; they only warn when it is not, because a missing tool does not
  mean a missing driver.
- the X display is probed with xdpyinfo in the environment Darling inherits.
  It only warns: a build does not need a display.
- a prepared build/darling-src is scanned for small .dylib/.a/.so/.o files
  that still contain Git LFS pointer text, which links but crashes the guest.
- --json prints the same report for the diagnostic tools.

The installers no longer call hashlib.file_digest (Python 3.11+), so Ubuntu
22.04's Python 3.10 works instead of failing after the overlays are built
(#137). A streaming tools/file_digest.py replaces it.

LLVM command line tools are resolved by tools/llvm_tools.py: an unversioned
name on PATH first, then the highest llvm-<tool>-<N>, then llvm-config
--bindir. Debian/Ubuntu install llvm-objdump and llvm-nm only under
/usr/lib/llvm-<N>/bin, which broke the runtime validation (#138). Six tools
now use it. The LLVM 16 floor also stops the LLVM 15 runtime abort from #139
before anything is built.

Two test helpers used APIs added after Python 3.10; they are shimmed so the
same suite runs on 3.10, 3.11 and 3.14.

Adds tests/test_preflight.py (24 tests, fake host tools only).
2026-10-25 13:58:25 -06:00
lucannez64andClaude Opus 5.5 a11a144767 Merge main into fix/recover-stale-client
Resolve conflicts with #122: keep both feature docs and CI steps, and drop
this branch's copy of the close-helper block, which main now starts after
the installed-client check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-23 14:18:33 +02:00
3AvisD 9194beef2f fix(launcher): harden stale-client recovery
- fail closed when X11 omits _NET_CLIENT_LIST or WM_CLASS, and recognize the
  RiotClientServices window class;
- require stale client processes to be at least 60 seconds old;
- recheck process identity before SIGTERM and SIGKILL and recheck the window
  before signalling;
- document the age and window-detection guards.
2026-10-23 06:08:45 -06:00
3AvisD f8bb14624e fix(launcher): address in-game helper review
- restore hidden windows even when the launcher output pipe is closed;
- exit the hide watcher after ten idle minutes and start it only after the
  installed-client check;
- reject missing, malformed or invalid close-during-game preferences instead
  of silently selecting hide;
- document the preference contract and idle behavior.
2026-10-23 06:08:45 -06:00
3AvisD 0a04d4e16c fix(launcher): remove orphaned client-in-game helpers
A launcher can exit while its long-lived close/hide helper remains. The next
run then starts another watcher, so several copies watch the same prefix.

Add an opt-in RCLOL_CLEAN_STALE_HELPERS=1 preflight that removes only helper
processes of this prefix reparented to init/systemd. Helpers of a live
launcher, other prefixes, the game, Riot/League/CEF, darlingserver and the
runtime are preserved. Unreadable or relative process data leaves a process
alone.

Validated across repeated launcher starts: the cleanup removed four, then one,
then one orphaned watcher; a subsequent dry run reported no orphaned helpers.
Zombie reaping after partial recovery is tracked separately in #124.
2026-10-22 15:50:38 -06:00
3AvisD c8dd3886fc fix(launcher): recover a stale client tree without restarting Darling
Darlingserver normally stays alive after the Riot Client or game is closed.
If the client window disappears but Riot/League/CEF processes remain,
restarting via run.sh reuses a half-dead runtime and can fail to open a
window.

Add an opt-in RCLOL_RECOVER_STALE_CLIENT=1 preflight. When a darlingserver is
alive, no game is running, no managed client window is visible and stale
client processes belong to this prefix, stop only that client/CEF tree.
Preserve darlingserver, launchd/mldr, sockets and .init.pid, then continue
with the normal product launch.

The helper fails closed when X11 is unavailable, never touches a running game
or a visible client window, and does not patch client binaries, CEF or assets.
It saves the Darling bootstrap, but not Riot Client/CEF startup; a full runtime
restart remains the fallback if no window appears.
2026-10-22 15:27:33 -06:00
3AvisD 4faa622336 feat(launcher): select client-in-game mode from preferences
Add RCLOL_CLIENT_IN_GAME_TRICKS=1 as the practical launcher switch. It reads
lol-user-experience from LCULocalPreferences.yaml:

- potatoModeEnabled false or unreadable: no action;
- closeLeagueClientDuringGame true: close the client UI;
- closeLeagueClientDuringGame false: hide the client windows.

The existing close and hide switches remain low-level options when the
automatic switch is not set. The hide helper accepts the master switch, and
the resolver plus preference cases are covered by tests and documentation.

The local .desktop entry was validated with the master switch; the installed
preferences select hide on this machine.
2026-10-22 14:56:03 -06:00
3AvisD 415aa7a949 feat(launcher): hide the League client UI while a match runs
Add an opt-in alternative to closing LeagueClientUx: hide the managed
LeagueClientUx and Riot Client X11 windows while the game process runs and
show them again when it exits. The client stays open; the game window is
never touched.

Detection is attributed to the launcher prefix through __mldr_sockpath and
fails closed when proc, ownership or window state is unreadable. The helper
requires X11/Xwayland, restores the window on end, signal or error, and is
mutually exclusive with RCLOL_CLOSE_CLIENT_IN_GAME=1.

Document the flag, compliance scope and limits. A local 30-second test on an
i5-3470/RX 550 reduced summed client/CEF CPU from 120.7% to 93.4%; this is a
CPU-bound-host measurement, not a universal FPS claim.

No client binaries, CEF, assets or anti-cheat are modified.
2026-10-22 12:15:35 -06:00
lucannez64 e00ee99522 fix(launcher): only remove launcher artifacts this project created
Match the legacy entry against this checkout's desktop-run.sh instead of any
desktop-run.sh, and delete the legacy icon files only after that entry or the
old artwork proves ownership.  Quote and escape Exec arguments as the Desktop
Entry specification requires, so a checkout path with reserved characters no
longer produces an invalid entry, and escape the Path value.

Use StartupWMClass=RiotClientServices in both entries: Darling derives WM_CLASS
from -[NSProcessInfo processName], the basename of argv[0], and the launcher
starts .../RiotClientServices.  "Riot Client" is only the bundle display name,
so the checkout entry never matched the window.  Both entries now share
Name/GenericName/Comment/Icon/Keywords/Categories and a test keeps them in
sync; Terminal stays different because the checkout entry logs to
build/desktop-launch.log while the packaged entry runs the session in a
terminal.

Also drop the stray top-level icon copies, handle dangling legacy symlinks,
name the icon for assistive technology, document the alias and menu entry, and
cover the helper with disposable-HOME tests.
2026-10-21 17:38:42 +02:00
lucannez64 c686798ddb test(nix): run font compatibility regressions in CI 2026-10-20 13:57:05 +02:00
Nicolai Bruns a089a23072 fix(nix): harden fontconfig compatibility across host setups 2026-10-20 13:31:02 +02:00
nbandlucannez64 0d8da88894 fix: preserve ambiguous guest processes during prefix cleanup (#111)
* fix: preserve ambiguous guest processes during prefix cleanup

* fix: warn only for matching runtime cleanup candidates

---------

Co-authored-by: lucannez64 <[email protected]>
2026-10-20 13:02:29 +02:00
nbandKalah 0a9a75e820 fix(appkit): add NSSavePanel tag-name compatibility (#112)
Co-authored-by: Kalah <[email protected]>
2026-10-20 12:24:10 +02:00
Kalah e727049d67 Fix Nix FHS text fonts and fontconfig aliases (#113) 2026-10-20 12:14:32 +02:00
Kalah c2f71e23fe Merge branch 'main' into fix/darlingserver-fd-limit 2026-10-20 11:57:42 +02:00
3AvisD 75da66c1ea docs: add scope and terminology guidance
Add docs/COMPLIANCE.md with the project's compatibility scope: no DRM/anti-cheat circumvention, no third-party game assets, and neutral terminology for issues and PRs. Link it from README and NOTICE.
2026-10-19 23:06:47 -06:00
3AvisD 54edf6fca1 patches, tools, docs: use neutral integrity-check wording and state the compatibility scope
The patch comments and the Mach-O strings filter named an anti-cheat product. Use neutral wording; the patches still differ only in comments. The platform-identity document now says the overrides are for compatibility, not a bypass of anti-cheat, telemetry, licensing or platform controls.
2026-10-19 22:47:59 -06:00
David GhegheaandClaude Opus 5.5 c4135ab79f Raise darlingserver's soft fd limit when the hard limit is fixed
Under the rootless NixOS launcher darlingserver cannot raise its hard
RLIMIT_NOFILE to nr_open, so it kept the soft limit it inherited. Every
named memory entry holds a memfd in darlingserver, and its descriptors
peak at about 1100 when the League lobby opens. With an inherited soft
limit of 1024, memfd_create failed with EMFILE, mach_make_memory_entry_64
returned KERN_RESOURCE_SHORTAGE, and Chromium's CHECK in
PlatformSharedMemoryRegion::Create killed the League UX and the Riot
Client renderer after clicking Play.

When raising the hard limit fails, raise the soft limit to the inherited
hard limit instead. Log errno, size and fd limits when named-entry
creation fails, and log the live memfd count every 1024 creations so a
leak shows up in dserver.log.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 22:45:23 +02:00
Kalah d4d5d8adc9 Merge branch 'main' into docs/nvidia-reports 2026-10-19 19:08:01 +02:00
lucannez64 5f71c82dc5 Bypass proxies when checking guest DNS 2026-10-19 18:22:17 +02:00
Polar bf02f7abee Document NVIDIA reports instead of "NVIDIA is not validated" 2026-10-19 16:21:26 +00:00
lucannez64 e47f05f424 Use the host DNS resolver in Darling 2026-10-19 18:11:49 +02:00
lucannez64 ff8a985057 Merge current main into the tested VSync and VRR fixes 2026-10-19 12:59:58 +02:00
lucannez64 6bfdfbcac7 Merge VSync and VRR fixes for combined testing 2026-10-19 12:15:09 +02:00
lucannez64andClaude Sonnet 5.5 70a2feec42 Add standalone NSOpenPanel Open/Cancel probe for issue #85
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-19 09:19:42 +02:00
lucannez64 041591352e Present full-window Metal layers on the managed X11 surface for VRR 2026-10-19 07:35:16 +02:00
ekisu 8f97990d03 Implement Cocoa local event monitors for native client dragging 2026-10-19 01:15:03 -03:00
ekisu 41da6d9e0a Fix X11 decorations for client-drawn Cocoa windows
Synchronize Motif decoration hints on style and titlebar-property changes, including native-window recreation and restoring ordinary WM decorations. Add a ten-case standalone Cocoa/X11 regression probe and document validation on KWin/Xwayland.
2026-10-18 21:06:22 -03:00
lucannez64 27553d8874 Fix Metal VSync propagation to window swap intervals 2026-10-19 01:10:03 +02:00
lucannez64andClaude Opus 5.5 c8cbb1ffe7 install-runtime.sh: provision a platform identity for new prefixes
When install-runtime.sh creates the prefix (first-time setup, regular or
Nix), it now runs configure-darling-platform.py --provision --write once
the runtime is stopped, so each new install gets its own synthetic serial,
MLB, UUID and ROM. A prefix counts as new the same way Darling decides it:
the directory did not exist before the first `darling shell`. Existing
prefixes keep their identity on reinstall and update.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 00:22:07 +02:00
lucannez64andClaude Opus 5.5 d443e631c2 update.sh: replace the shared serial and UUID automatically
Older setups shipped serial C02ZL0GVMD6N and UUID
6F3B2A1E-8C4D-4E5F-9A7B-1D2C3E4F5A6B to every install. After installing,
update.sh now runs configure-darling-platform.py --replace-known-defaults,
which provisions the prefix only when its saved identity still has one of
those values. Other custom values (imported serials/UUIDs, model, board,
manufacturer, ROM, MLB) are kept; prefixes with no saved identity or only
custom values are not touched.

provision() also drops a standalone system-id or provisioning_UDID derived
from the shared UUID instead of keeping it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 00:17:22 +02:00
Kalah 0b02889968 Merge pull request #72 from 3AvisD/fix/close-league-client-in-game
fix(launcher): close the League client UI while a match runs
2026-10-18 20:56:18 +02:00
lucannez64andClaude Opus 5.5 9f62aa3ce0 close-league-client-in-game: start the idle clock only after a client was seen
A long patch or login can keep the League client closed for more than ten
minutes after launch; the helper then left before the first match.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 20:48:43 +02:00
3AvisD 72eb402cd4 fix(launcher): keep Mesa's shader cache on the host
Mesa derives its shader disk cache from $HOME. Inside the guest that is
/Users/<user>, which does not exist on the host filesystem, so Mesa could not
create the cache and disabled it, once per process:

    Failed to create /Users/<user> for shader cache (Permission denied)---disabling

One launcher log contained 212 of those lines, and no shader compiled by one
process was reused by another process or by the next start: the client and the
game recompiled every shader on every launch, spending CPU at startup for no
gain.

Mesa is host code loaded into the guest and reads MESA_SHADER_CACHE_DIR verbatim,
so point it at a host directory; Mesa creates mesa_shader_cache/ (client and game
shaders) and radv_builtin_shaders/ below it. A non-empty value from the caller is
preserved, and a directory that cannot be created leaves the previous behaviour
instead of ending the launch.

Observed on a Radeon RX 550 with radv: no shader-cache failure after the change,
and 434 files / 5.6 MB written during one client start, still growing while the
client ran. The cache is reused from the second start on, which lowers the
client's CPU use while it starts; the startup-time gain itself has not been
measured separately.
2026-10-18 12:18:33 -06:00
3AvisD 823fa6addc fix(launcher): close the League client UI while a match runs
The client does not come back properly after a match when its own "Close client
during game" option is enabled. The UI (LeagueClientUx and its helpers) is a
Chromium/CEF instance and, under Darling, the pre-match instance keeps running:
the client the backend starts when the match ends is a second CEF instance on the
same --user-data-dir, and its window never paints. Its DOM and audio work and the
window stays black; closing the client by hand during a match leaves the same
state for the same reason.

RCLOL_CLOSE_CLIENT_IN_GAME=1 opts in to closing that UI from the host, and only
while a match runs, so the client that appears afterwards is the only instance.
The UI also competes with the game for CPU: on a four-core host with a Radeon
RX 550 a practice match reported roughly 120 FPS with the UI running and roughly
180 FPS with it closed. This is not the helper-killing memory optimization the
RAM section warns against, and the Riot client, the League backend and the game
are never touched.

The helper fails closed. It attributes the game and the client to the launcher's
prefix through the loader's __mldr_sockpath, since guest processes do not carry
DPREFIX (checked on a live session). It never closes a client younger than 60
seconds (the one the backend starts after a match), preserves a process of
another installation or owner, acts only when the environment and the stat fields
can be read, gives up after three closes in one match, and leaves after ten
minutes without a client or a match. It is off by default.

Tests use fake /proc entries and mock every signal.
2026-10-18 12:18:33 -06:00
lucannez64andClaude Sonnet 5.5 20d8320bf6 Make --set-prefix safe against data loss
Stage a cross-filesystem copy in a private directory instead of deleting a
pre-existing PATH.partial, reject destinations inside the overlay work
directory, save the new path before deleting the old prefix, and verify that
the target keeps user.* xattrs before and after copying. Add tests.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-18 19:04:30 +02:00
lucannez64 640f31d148 Merge remote-tracking branch 'origin/main' into pr70 2026-10-18 19:03:04 +02:00
lucannez64andClaude Sonnet 5.5 7ef148c76e Add standalone X11 drag-and-drop check for PR #63
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-18 18:59:43 +02:00
David GhegheaandClaude Opus 5.5 8c25542b31 Add darling-lol --set-prefix to keep the prefix on another drive
The prefix holds the installed clients and game (about 40 GB). The Nix
launcher always exported DPREFIX=${DPREFIX:-~/.darling}, so the prefix saved
in build/config.json was never used and the only way to move it was an
environment variable in every launch context.

- The launcher uses DPREFIX if set, then the saved prefix, then ~/.darling.
- darling-lol --set-prefix PATH runs scripts/nix-prefix.py in the namespace,
  whose root owns the prefix files, so cp -a keeps their owners and xattrs.
  It renames the prefix when possible; across filesystems it copies to
  PATH.partial and removes the old prefix and its overlay work directory
  only after the copy completes. A PATH that already holds a Darling prefix
  is used as it is. It refuses non-empty directories that are not prefixes,
  nested paths and paths with commas or colons (overlayfs separators), then
  saves the path with configure.py --prefix.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 18:32:14 +02:00
Kalah dd6a4fad78 Merge branch 'main' into feat/stop-and-signal-cleanup 2026-10-18 18:15:02 +02:00
lucannez64 b53b963997 Merge remote-tracking branch 'origin/main' into pr61/system-profiler-overview
# Conflicts:
#	.github/workflows/source-check.yml
2026-10-18 17:32:11 +02:00
lucannez64 fd0d01e813 Merge remote-tracking branch 'origin/main' into pr61/metal-device-fixes
# Conflicts:
#	.github/workflows/source-check.yml
2026-10-18 17:31:14 +02:00
lucannez64andClaude Opus 5.5 29e35b6a93 Report the MacBookPro16,1 GPU name for Riot on AMD and Intel hosts
With DARLING_METAL_MAC_GPU_NAME=1, MTLDevice.name is the GPU the
MacBookPro16,1 that IOKit reports shipped with, from the host's vendor:
"AMD Radeon Pro 5500M" (vendor 0x1002) or "Intel UHD Graphics 630"
(0x8086). NVIDIA keeps its own name so the game never takes another
vendor's driver paths. recommendedMaxWorkingSetSize and every other value
stay the host's, which was the risky part of #61's identity.

The Riot launcher turns it on by default (0 or empty turns it off); other
Darling apps keep the host name. DARLING_METAL_GPU_NAME still wins.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 17:24:49 +02:00
beb64a4271 Report hardware and software overviews from IOKit and sysctl in system_profiler
system_profiler now answers SPHardwareDataType and SPSoftwareDataType (and
lists them in -listDataTypes). Model, serial number, platform UUID and
provisioning UDID come from IOKit's IOPlatformExpertDevice via ioreg; CPU,
cache and memory from sysctl; the OS version from sw_vers and uname. A
field the guest does not provide is left out.

#61 instead read a separate darling-smbios.conf written by a new
generator (gen-darling-smbios.py), with hardcoded fallbacks (an Intel Core
i9, macOS 14.7, SIP enabled). iokitd reads darling-platform.plist, so
system_profiler and IOKit could report different serials and models on the
same prefix, and the generator overwrote identities imported with
configure-darling-platform.py. Reading the guest's own APIs keeps a single
source of truth: configure-darling-platform.py remains the only way to set
or provision an identity, and it is still never run by install or launch.

tests/test_system_profiler.py runs the script under sh with stub guest
commands and runs in CI.

Split from #61.

Co-authored-by: DevWebeloper <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 17:17:05 +02:00
e66bd9a394 Fix Metal device edge cases; keep reporting the host GPU
From #61, without the default "AMD Radeon Pro 5500M" / 4 GB identity: the
host GPU's name and Vulkan working set stay the default for every app, and
the existing DARLING_METAL_GPU_NAME and DARLING_METAL_VRAM_MB overrides
remain the opt-in. Reporting 4 GB on a 2 GB card invites allocation
failures, and under-reports larger cards.

Kept from #61:
- registryID returns MTLDeviceInfo::kDefaultRegistryID instead of 0; a
  real Mac never reports 0 and apps key devices by it.
- Vertex buffer layout and attribute arrays release the old item after
  retiring it; the retire step read the item after the release could free it.
- newDepthStencilState, newSamplerState and the device name return nil (or
  the fallback name) when Indium throws, instead of unwinding through
  Objective-C.
- MTLDepthStencilGetIndium is declared only with DARLING_METAL_ENABLED.
- The replaceRegion trace probes at most `width` bytes, which stays inside
  the first row for every pixel format.

metal.patch is regenerated in its existing file order, so the diff is
these changes only. tests/test_metal_device_info.py compiles the host
check against MTLDeviceInfo.h as shipped in the patch and runs in CI.

Split from #61.

Co-authored-by: DevWebeloper <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 17:14:47 +02:00
David GhegheaandClaude Opus 5.5 033ded4fd6 Stop Darling on Ctrl+C, terminal hangup and darling-lol --stop
After the clients quit, the session kept Darling running: Riot and League
crash handlers never exit under Darling, and the idle check counted them as
clients. Ctrl+C or closing the terminal killed bubblewrap, whose
--die-with-parent then killed nix-lifecycle.py before it could shut Darling
down, which left a live server marker behind.

- nix-idle.py ignores crash handlers when deciding whether a client still
  uses the prefix.
- The launcher starts bubblewrap with INT, QUIT, HUP and TERM ignored, and
  env restores them inside. The supervisor turns them into a stop request.
- nix-lifecycle.py polls for a signal or stop request and then shuts Darling
  down without waiting for clients. It stops retrying a failed shutdown once
  the server is gone, and waits for or kills its own command afterwards.
- darling-lol --stop makes the stop request and waits for the session. If
  the session does not exit within 30 seconds, or no session holds the lock,
  it kills the prefix's darlingserver and launchd like darling shutdown,
  after checking that the marker PID is this user's darlingserver for this
  prefix.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 17:14:26 +02:00
41b5b6fc0f Add an opt-in filter for host desktop-session variables
RCLOL_FILTER_HOST_ENV=1 makes exec-guest.py drop host session metadata
(WAYLAND_DISPLAY, XDG_SESSION_*, XDG_CURRENT_DESKTOP, GNOME/KDE/GDM,
systemd, SSH agent, terminal, toolkit, Flatpak/Snap/AppImage, exported
shell functions) and set SHELL to the guest's /bin/zsh. It is off by
default; RCLOL_KEEP_HOST_ENV lists names to keep anyway.

Unlike the denylist in #61, the filter runs after the launcher sets its
GPU tuning, keeps everything Darling and the host graphics and audio
libraries read (DISPLAY, XAUTHORITY, XDG_RUNTIME_DIR and the XDG base
directories, D-Bus, PulseAudio/PipeWire/ALSA, DRI_PRIME, MESA_*, __GL_*,
__NV_*, VK_*, LD_PRELOAD for gamemoderun, LD_LIBRARY_PATH), and lives in
one place instead of three.

tests/test_exec_guest.py runs in CI; the launcher check also verifies
that MESA_NO_ERROR=1 and __GL_THREADED_OPTIMIZATIONS=0 reach the guest
with the filter on.

Split from #61.

Co-authored-by: DevWebeloper <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 17:13:24 +02:00
6d3e870346 Close inherited host file descriptors before starting the guest
A terminal, IDE or service manager can leave descriptors open in the
launcher, and the guest inherited all of them. tools/exec-guest.py closes
every descriptor above stderr and then execs the guest command.

A shell loop over /proc/self/fd cannot do this portably: dash only parses
single-digit descriptors in redirections, so "exec 10>&-" runs a command
named 10 and ends the launcher on Debian and Ubuntu.

The launcher offline check now leaks descriptors 3, 4, 12 and 200 into the
launcher and asserts the guest sees only 0, 1 and 2. It runs in CI.

Split from #61.

Co-authored-by: DevWebeloper <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 17:11:36 +02:00
lucannez64 0830f08c3f Merge remote-tracking branch 'origin/main' into fix/pr58-docs 2026-10-18 15:19:05 +02:00