macOS sandbox exec hangs after output (job-control SIGTTIN when setpgid + inherited stdio)

Resolved 💬 0 comments Opened Jan 2, 2026 by seeekr Closed Jan 8, 2026

Summary

On macOS, Codex sandboxed exec (including the transparent exec path used by the agent, not just the codex sandbox CLI) can hang after commands like elixir -v. The command prints output then never exits. This blocks running Mix/Elixir commands in Codex.

Reproduction

codex sandbox macos --full-auto /bin/sh -c 'elixir -v; echo DONE'
# prints Elixir version, then hangs (no DONE)

codex sandbox macos --full-auto /bin/sh -c 'erl -noshell -eval "io:format(\"ok~n\"), halt()."; echo DONE'
# prints ok, then hangs

Environment

  • macOS (Apple Silicon, arm64)
  • Elixir 1.19.4 / Erlang OTP 28
  • Codex commit: 82fcc087b5ff949820aec0c48d3ea2194928f2e3

Root Cause

Codex’s spawn path calls setpgid(0,0) unconditionally on Unix. When stdio is inherited (i.e., connected to the controlling TTY), the child ends up in a background process group. If it reads from the TTY, the OS sends SIGTTIN and stops the process. This looks like a hang after output.

Proposed Fix

Only call setpgid when stdio is redirected (piped output for shell tool). When stdio is inherited, keep the child in the parent’s process group. This avoids job-control stops while preserving killpg cleanup for piped/redirected commands.

Status

I have a local change implementing the above and can open a PR shortly. The fix is in core/src/spawn.rs.

---
Filed by @seeekr with assistance from Codex AI; we’re working together and will provide a PR soon.

View original on GitHub ↗