← Commit history

v0.9.2 defensive subprocess

John Lauer ·26f3e19156 ·3mo ago ·parent 8897c42
1 file changed +27
proc.pyadded+27
@@ -0,0 +1,27 @@+"""Safe subprocess wrapper — defensive against host spawn environments.++When a supervisor (Adom Desktop) spawns this bridge, the bridge's own child+processes must NOT inherit a broken/null console handle or an open stdin, or+calls like `subprocess.run(... capture_output=True)` can deadlock during startup+(observed 2026-06-25: KiCad detection hung forever under AD's spawn, but ran fine+when launched from a normal shell). AD ≥1.8.185 hardened its side (valid log+handles); this hardens ours so the bridge is robust under ANY supervisor.++Always: detach stdin (DEVNULL) and, on Windows, CREATE_NO_WINDOW so no console+pops and no console handle is inherited. Callers still pass their own+capture_output/text/timeout.+"""++import subprocess+import sys++IS_WINDOWS = sys.platform == "win32"+_CREATE_NO_WINDOW = 0x08000000  # win32 process creation flag+++def run(cmd, **kwargs):+    """Drop-in for subprocess.run with safe defaults for a spawned-bridge context."""+    kwargs.setdefault("stdin", subprocess.DEVNULL)+    if IS_WINDOWS:+        kwargs["creationflags"] = kwargs.get("creationflags", 0) | _CREATE_NO_WINDOW+    return subprocess.run(cmd, **kwargs)