[php-src] Issue #24229: fcgi_close() passes shutdown() a literal 1, which is SHUT_RD in WASI
| From: | mpyw | Date: | Fri, 09 Oct 2026 20:26:45 +0000 |
| Subject: | [php-src] Issue #24229: fcgi_close() passes shutdown() a literal 1, which is SHUT_RD in WASI | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-252958@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/24229
Author: mpyw
The quoted description below was written with an LLM (Claude). I reviewed it, and ran the checks it
describes myself.
> ### Description
>
>
fcgi_close() in main/fastcgi.c
> half-closes the connection with a literal 1:
>
> ```c
> if (!force) {
> char buf[8];
>
> shutdown(req->fd, 1);
> /* read any remaining data, it may be omitted */
> while (recv(req->fd, buf, sizeof(buf), 0) > 0) {}
> }
> close(req->fd);
> ```
>
> 1 means SHUT_WR only where
> SHUT_WR is 1. POSIX names the constants, but does not fix their
> values. Every platform PHP supports today uses 1, and Windows'
> SD_SEND is 1 too, so nothing breaks there.
>
> WASI numbers them from 1 instead. wasi-libc's
> <__header_sys_socket.h> has:
>
> ```c
> #define SHUT_RD 1
> #define SHUT_WR 2
> #define SHUT_RDWR (SHUT_RD | SHUT_WR)
> ```
>
> So a php-cgi built for wasm32-wasip1 shuts the reading side
> instead. The drain loop then ends at once, and close() runs while
> the web server's last FCGI_STDIN record may still be unread.
> Linux answers that with a reset, which discards the response that php-cgi already sent but the web
> server had not read yet. The web server sees a broken pipe, or a connection reset, instead of
> FCGI_END_REQUEST.
>
> I hit this running php-cgi in FastCGI mode (-b) on wazero, a
> WebAssembly runtime, behind a Go FastCGI client. About 1 in 60 requests failed on Linux. macOS did
> not show it. With SHUT_WR, 600 requests in a row succeeded.
>
> The fix is to use the constant, as the comment means:
>
> ```diff
> - shutdown(req->fd, 1);
> + shutdown(req->fd, SHUT_WR);
> ```
>
> The _WIN32 branch has the same literal.
> SD_SEND would be the matching name there, though
> 1 is correct on Windows.
>
> I know WASI is not a target PHP supports. I am reporting it because the change is one line, it
> says what the comment already says, and it costs nothing on the supported platforms. I can send a PR
> if that is welcome.
>
> ### PHP Version
>
> ```
> PHP 8.6.0RC3
> ```
>
> The same literal is on master, PHP-8.6, PHP-8.5 and PHP-8.4 as of 2026-10-10.
>
> ### Operating System
>
> Only with WASI (wasm32-wasip1, built with wasi-sdk 34), here on
> Linux. Not reproducible on native builds.