Skip to content

Commit 532cf7c

Browse files
mios-devclaude
andcommitted
fix(launcher): broker must never crash on its log write -> OS-control was dead
mios-launcher-daemon did os.makedirs("/var/log/mios-launcher") OUTSIDE the try/except, but it runs as the operator (uid 992) which cannot create under root-owned /var/log (the StateDirectory= the comment assumed is gone). So every dispatch raised "Permission denied: /var/log/mios-launcher" and aborted BEFORE launching -> open_app/open_url/all OS-control verbs failed even with the socket present (operator 2026-06-21 "open notepad" then nothing). Per-dispatch log is now best-effort to an operator-writable dir (/run/mios-launcher/log) and falls back to DEVNULL on ANY error so the app ALWAYS launches. Live-verified: notepad opens via the broker after this. install-robustness 2026-06-21. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 600df69 commit 532cf7c

1 file changed

Lines changed: 25 additions & 9 deletions

File tree

usr/libexec/mios/mios-launcher-daemon

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,20 +172,36 @@ def handle(conn: socket.socket) -> None:
172172
# AGAIN").
173173
env = dict(os.environ)
174174
env.setdefault("GDK_BACKEND", "wayland")
175-
# Stream stdout/stderr to a per-dispatch log under /var/log/
176-
# mios-launcher/ so debug-able. Service has StateDirectory= so
177-
# the dir is auto-created + writable.
178-
log_dir = "/var/log/mios-launcher"
179-
os.makedirs(log_dir, mode=0o755, exist_ok=True)
180-
ts_id = subprocess.check_output(["date", "+%Y%m%d-%H%M%S-%N"]).decode().strip()
181-
log_path = os.path.join(log_dir, f"dispatch-{ts_id}.log")
175+
# Per-dispatch log -- BEST-EFFORT, must NEVER block the launch. The
176+
# daemon runs as the operator (uid 992) and CANNOT create under
177+
# /var/log (root-owned); the old StateDirectory= assumption is gone, so
178+
# os.makedirs("/var/log/mios-launcher") raised Permission denied and
179+
# aborted the WHOLE dispatch -> no app ever launched (operator
180+
# 2026-06-21 "open notepad" -> broker logged "dispatch: notepad.exe"
181+
# then died "Permission denied: /var/log/mios-launcher"). Log to the
182+
# operator-writable runtime dir, and fall back to DEVNULL on ANY error
183+
# so the app still launches. install-robustness 2026-06-21.
184+
log_fp = None
185+
log_path = "(none)"
182186
try:
187+
log_dir = os.environ.get("MIOS_LAUNCHER_LOG_DIR", "/run/mios-launcher/log")
188+
os.makedirs(log_dir, mode=0o755, exist_ok=True)
189+
ts_id = subprocess.check_output(["date", "+%Y%m%d-%H%M%S-%N"]).decode().strip()
190+
log_path = os.path.join(log_dir, f"dispatch-{ts_id}.log")
183191
log_fp = open(log_path, "w")
184-
os.chmod(log_path, 0o644)
192+
try:
193+
os.chmod(log_path, 0o644)
194+
except OSError:
195+
pass
196+
except OSError as e:
197+
log.warning("per-dispatch log unavailable (%s) -- launching without a log file", e)
198+
log_fp = None
199+
log_path = "(none)"
200+
try:
185201
proc = subprocess.Popen(
186202
["bash", "-lc", line],
187203
stdin=subprocess.DEVNULL,
188-
stdout=log_fp,
204+
stdout=(log_fp or subprocess.DEVNULL),
189205
stderr=subprocess.STDOUT,
190206
start_new_session=True,
191207
env=env,

0 commit comments

Comments
 (0)