|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-02-03 15:44 UTC] patryk dot szczyglowski at gmail dot com
Description:
------------
When PHP wants to read from a blocking socket when the remote host disconnects, PHP ignores 0 return code from recv() system function and drops into endless loop.
Reproduce code:
---------------
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, $ip, $port);
// disconnect remote host here
$rcv = socket_read($this->socket, 65536, PHP_BINARY_READ); // this line never returns
Expected result:
----------------
socket_read returns with FALSE
--- php-5.2.8/ext/sockets/sockets.c.orig 2008-10-23 22:21:30.000000000 +0200
+++ php-5.2.8/ext/sockets/sockets.c 2009-01-29 17:32:53.000000000 +0100
@@ -903,6 +903,14 @@
RETURN_FALSE;
}
+ if (retval == 0) {
+ php_sock->error = errno;
+ SOCKETS_G(last_error) = errno;
+
+ efree(tmpbuf);
+ RETURN_FALSE;
+ }
+
tmpbuf = erealloc(tmpbuf, retval + 1);
tmpbuf[retval] = '\0' ;
Actual result:
--------------
socket_read never returns, it gets looped in ext/sockets/sockets.c:885
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Nov 01 00:00:01 2025 UTC |
In php documentation: "socket_read() returns the data as a string on success, or FALSE on error (including if the remote host has closed the connection)." So I used: while (($res = socket_read(...)) !== false) { // .. do something } To correct it without changes in PHP source code this loop should look: while ($res != false) { // .. do something } but that's incorrect, because e.g. string '0' will match the condition and it is perfectly valid content. Low level recv() function returns 0 only on disconnect, and while connected in blocking mode 0 is never returned to the application. Current PHP implementation is not compatible with recv(2) and PHP documentation. So either you commit my patch or correct the documentation. Thanks.