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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions