From 14a8a474120ef4289625f05ba5d87fa9e9d19542 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Thu, 6 Aug 2026 20:50:24 +0900 Subject: fix(php-rpc): carry the worker channel over a socketpair The transport bound an AF_UNIX path under TMPDIR and waited for the child to connect. That path has to fit in sun_path (108 bytes), so a deep TMPDIR made every worker spawn fail, and the bind(2) itself is denied under a sandbox. The parent now keeps one end of a socketpair and installs the other on descriptor 3 before exec, which the worker opens as php://fd/3. The pair is connected from the start, so the accept poll and its ten-second deadline are gone; a child that dies before reading surfaces as EOF on the first call, where worker_state already attaches its exit status. Co-Authored-By: Claude Opus 5 (1M context) --- docs/dev/php-rpc.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'docs/dev/php-rpc.md') diff --git a/docs/dev/php-rpc.md b/docs/dev/php-rpc.md index e55f860e..77d0d365 100644 --- a/docs/dev/php-rpc.md +++ b/docs/dev/php-rpc.md @@ -17,11 +17,16 @@ behavior. ## Transport -- A Unix domain socket (no Windows support for now), bound in a `0700` temp dir with the socket - file itself chmodded to `0600`. +- A `socketpair(2)` (no Windows support for now). The parent keeps one end and installs the + other on descriptor 3 in the child, from a `pre_exec` hook, so the worker opens it as + `php://fd/3` rather than connecting anywhere. A bound path would have to fit in `sun_path` + (108 bytes), which a long `TMPDIR` overruns, and it needs a `bind(2)` that sandboxes commonly + deny. The pair is connected from the start, so nothing has to wait for an `accept` either: a + child that dies before reading surfaces as EOF on the first call, with its exit status + attached. - The PHP glue code (`php/worker.php`) and the proxy stub classes (`php/stubs/`) are embedded in - the Rust binary and written to the temp dir at spawn time, so both halves of the protocol are - always the same commit. + the Rust binary and written to a `0700` temp dir at spawn time, so both halves of the protocol + are always the same commit. ### Frame layout -- cgit v1.3.1