Skip to content

Quality: popen path in shell.exec has no timeout at all on Linux and macOS #65

Description

@KrisPowers

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions