[php-src] PR #24174: Fix GH-24173: Sockets left in non-blocking mode on Windows
| From: | vibbow | Date: | Wed, 07 Oct 2026 08:00:41 +0000 |
| Subject: | [php-src] PR #24174: Fix GH-24173: Sockets left in non-blocking mode on Windows | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-39232@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/24174
Author: vibbow
Fixes #24173.
php_network_connect_socket() switches the socket to non-blocking mode for the connect,
and for a synchronous connect it is supposed to restore the original mode afterwards. On Windows,
SET_SOCKET_BLOCKING_MODE() sets save = TRUE, and FIONBIO
doesn't write back the previous mode. So RESTORE_SOCKET_BLOCKING_MODE() passed
TRUE again, and the socket stayed non-blocking while the stream reported blocked
=> true. Paths that call recv() without polling first, such as
stream_socket_recvfrom() and socket_import_stream() +
socket_read(), then failed immediately with WSAEWOULDBLOCK.
Winsock can't query a socket's blocking mode. However, all callers of
php_network_connect_socket() pass freshly created sockets, which are blocking:
php_network_connect_socket_to_host(), the Unix socket connect in
xp_socket.c, and php_connect_nonb() in ext/ftp. So this restores to
blocking, which matches the POSIX behavior. Async connects don't call RESTORE, so
they are unaffected.
The test is Windows-only. It sets a 100 ms SO_RCVTIMEO on the imported socket and reads
with no data available. A blocking socket times out with SOCKET_ETIMEDOUT; a
non-blocking one fails at once with SOCKET_EWOULDBLOCK. On Windows, the test fails
without the fix and passes with it.
Also tested on Windows 11 with a minimal NTS x64 build:
- With the reproducer from the issue, all three cases now wait for the data, about 300 ms each.
- stream_set_timeout() + fread() still times out as expected.
- stream_set_blocking($c, false) + fread() still returns immediately.
- Connect latency and refused/timed-out connects are unchanged.
This is independent of #24172 (GH-24171), which touches the same function.
🤖 Generated with [Claude Code](https://claude.com/claude-code)