Summary
Issue #54 covers the hard-coded 30-second timeout on the Windows path of `shell.exec`. The Linux/macOS path using `popen()` has no timeout at all and blocks the IPC dispatcher thread indefinitely if the child process hangs.
From `cpp/host/dispatch.cpp` (shell.exec handler):
- Windows path: `WaitForSingleObject(pi.hProcess, 30000)` -- at least has a 30-second cap
- POSIX path: `popen()` followed by `fgets()` in a loop with `pclose()` -- no timeout, no kill, no cancellation
A hung shell command on Linux/macOS will hold the dispatcher thread for the lifetime of the process. If multiple callers hit this (e.g., rapid git status refreshes against a frozen NFS mount), threads pile up with no way to reclaim them.
How to fix
Replace the `popen()` path with `fork()`/`execve()` + `waitpid(WNOHANG)` in a polling loop, with a configurable timeout (default 30 seconds for parity with Windows). On timeout, send `SIGKILL` to the child, drain remaining output, and return the partial result with a `timed_out: true` flag in the response.
This is the POSIX equivalent of what #54 recommends for Windows. Both should be fixed together.
Files
- `cpp/host/dispatch.cpp` (shell.exec handler, popen section)
Summary
Issue #54 covers the hard-coded 30-second timeout on the Windows path of `shell.exec`. The Linux/macOS path using `popen()` has no timeout at all and blocks the IPC dispatcher thread indefinitely if the child process hangs.
From `cpp/host/dispatch.cpp` (shell.exec handler):
A hung shell command on Linux/macOS will hold the dispatcher thread for the lifetime of the process. If multiple callers hit this (e.g., rapid git status refreshes against a frozen NFS mount), threads pile up with no way to reclaim them.
How to fix
Replace the `popen()` path with `fork()`/`execve()` + `waitpid(WNOHANG)` in a polling loop, with a configurable timeout (default 30 seconds for parity with Windows). On timeout, send `SIGKILL` to the child, drain remaining output, and return the partial result with a `timed_out: true` flag in the response.
This is the POSIX equivalent of what #54 recommends for Windows. Both should be fixed together.
Files