#!/usr/bin/env bash # Guarantee EXACTLY ZERO xenia instances, then clear the lock. Source or run. # # `run-canary` holds /tmp/xenia-canary.lock to enforce the "one emulator at a # time" rule. A `kill -9` orphans it, and the obvious unblock -- `rm -f` the lock # -- ALSO DISABLES THE GUARD FOR EVERY LATER LAUNCH. On 2026-08-30 that left # three instances live at once, all reading /tmp/xenia_pad.txt and sharing # display :98, which silently confounded an input experiment: a scripted press # reaches every instance while `screenshot` grabs whichever window is topmost. # The finding built on it had to be withdrawn. # # So: the lock is only ever removed AFTER the condition it guards against is # verified absent. Never `rm -f` it directly. # # . ensure_single_emulator.sh (or) ensure_single_emulator.sh emu_count(){ ps -C xenia_canary --no-headers 2>/dev/null | wc -l; } ensure_single_emulator() { local n; n=$(emu_count) if [ "$n" -gt 0 ]; then echo "ensure_single_emulator: $n instance(s) live — stopping them" # kill by NAME. `pkill -f xenia_canary` matches the shell running it and # kills the caller instead; that has happened three times in this corpus. ps -o pid= -C xenia_canary | xargs -r kill for _ in 1 2 3 4 5 6 7 8 9 10; do [ "$(emu_count)" -eq 0 ] && break; sleep 1; done if [ "$(emu_count)" -gt 0 ]; then ps -o pid= -C xenia_canary | xargs -r kill -9 for _ in 1 2 3 4 5 6 7 8 9 10; do [ "$(emu_count)" -eq 0 ] && break; sleep 1; done fi fi n=$(emu_count) if [ "$n" -ne 0 ]; then echo "ensure_single_emulator: REFUSING — $n instance(s) still live." >&2 echo " Do NOT rm the lock: it is the only thing stopping a second one." >&2 return 3 fi rm -f /tmp/xenia-canary.lock # safe now, and only now echo "ensure_single_emulator: 0 instances, lock cleared" return 0 } # run directly (not sourced) -> do it (return 0 2>/dev/null) || ensure_single_emulator