php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #21197 [PATCH] socket_read() outputs error with PHP_NORMAL_READ
Submitted: 2002-12-26 09:32 UTC Modified: 2007-07-22 23:01 UTC
Votes:96
Avg. Score:4.6 ± 0.7
Reproduced:89 of 89 (100.0%)
Same Version:53 (59.6%)
Same OS:74 (83.1%)
From: bool at boolsite dot net Assigned: jani (profile)
Status: Closed Package: Sockets related
PHP Version: 5.*, 4.* (2005-11-17) (cvs) OS: *
Private report: No CVE-ID: None
 [2002-12-26 09:32 UTC] bool at boolsite dot net
Hello

I have a source which works with PHP 4.1.x to PHP 4.2.x,
it's work perfectly. But with PHP 4.3RC4 (windows version,
client mode) I have this warning :
Warning: socket_read() unable to read from socket [0]: Op?ration r?ussie. in E:\PHP\KioobFTP\v0.7.1\KioobFTP_SocketMode.php on line 262

Then, the result of the function is FALSE. 
The socket is in blocking mode.
The code is :
$tmp=socket_read($this->stream,4096,PHP_NORMAL_READ);

Do you need others info ?

Thanks.

Bool

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-12-26 20:39 UTC] edink@php.net
If you omit the third parameter to socket_read() it seems to work fine. However, adding PHP_NORMAL_READ causes error as described in the bug report.
 [2003-08-26 02:00 UTC] bool at boolsite dot net
Ok, this is a short example : (a little echo server)

<?php
error_reporting(E_ALL);

$Port=6669;

if(($Sock=socket_create(AF_INET,SOCK_STREAM,0))<=0) {
	echo 'socket_create() a ?chou? : ',socket_strerror(socket_last_error($Sock)),"\r\n";
	exit;
	}
if(($Ret=socket_bind($Sock,0,$Port))<=0) {
	echo 'socket_bind() a ?chou? : ',socket_strerror(socket_last_error($Ret)),"\r\n";
	exit;
	}
if(($Ret=socket_listen($Sock,5))<=0) {
	echo 'socket_listen() a ?chou? : ',socket_strerror(socket_last_error($Ret)),"\r\n";
	exit;
	}

while(true){
	$MsgSock=socket_accept($Sock);
	if($MsgSock===false) {
        echo 'socket_accept() a ?chou? : ',socket_strerror(socket_last_error($MsgSock)),"\r\n";
        break;
        }
      else {
	    echo '=> Debut de la connexion...',"\r\n";
		$EndTime=time()+15;
		do{
            $buffer=socket_read($MsgSock,1024,PHP_NORMAL_READ);
            if($buffer===false) {
			    echo 'socket_read() a ?chou? : ',socket_strerror(socket_last_error($MsgSock)),"\r\n";
				break;
                }
            elseif(!$buffer){
				continue;
                }
            $buffer=trim($buffer);
			echo '< ',$buffer,"\r\n";
			if($buffer=='quit') {
				break;
                }

            $back='You sent : ['.$buffer.']';

			echo '> ',$back,"\r\n";
			socket_write($MsgSock,$back."\r\n");
            } while(time()<$EndTime);

        @socket_close($MsgSock);
        echo '=> End...',"\r\n";
        }
    }
socket_close($Sock);
?>
 [2004-03-11 11:06 UTC] nlopess@php.net
I've compilled PHP with cygwin/gcc and no error is produced. However, the build version from snaps.php.net gives that error.
 [2005-09-29 16:07 UTC] tommyo at gmail dot com
I installed the latest windows build PHP Version 5.1.0RC2-dev and the socket problem still exists.  I get:

Warning: socket_read() [function.socket-read]: unable to read from socket [0]: The operation completed successfully.

When I put PHP_NORMAL_READ for the read type parameter. Using the default or PHP_BINARY_READ works just fine for the same line of code.
 [2005-11-04 16:24 UTC] sniper@php.net
See also bug #35062
 [2005-11-04 19:30 UTC] mike@php.net
Here's a possible patch, but Wez probably knows better if there's a way to tell if a windows socket is in blocking mode...

Index: sockets.c
===================================================================
RCS file: /repository/php-src/ext/sockets/sockets.c,v
retrieving revision 1.171.2.2
diff -u -p -d -r1.171.2.2 sockets.c
--- sockets.c   3 Nov 2005 15:00:51 -0000       1.171.2.2
+++ sockets.c   4 Nov 2005 18:28:45 -0000
@@ -257,6 +257,12 @@ static int php_read(int bsd_socket, void
        int nonblock = 0;
        char *t = (char *) buf;

+/*
+ * fcntl(s, F_GETFL) will always fail for windows, and there's no way to
+ * determine if a socket is in blocking mode to my current knowledge, so we
+ * just omit this check; though that means we're always blocking on win32...
+ */
+#ifndef PHP_WIN32
        m = fcntl(bsd_socket, F_GETFL);
        if (m < 0) {
                return m;
@@ -264,6 +270,7 @@ static int php_read(int bsd_socket, void

        nonblock = (m & O_NONBLOCK);
        m = 0;
+#endif

        set_errno(0);


 [2005-11-05 01:36 UTC] nlopess@php.net
I was walking through the MSDN docs and I didn't also find anything.
But the best way (IMHO) is to store in the php_socket struct if the socket is blocking or not (and update that field in the socket_set_(non)block() functions). It also saves the fcntl syscall on nix systems.
 [2005-11-05 22:10 UTC] nlopess@php.net
I've made a patch that implements the idea of my last comment. The test case now works properly.
I haven't tested bug #35062 but it seems to be a different bug.
http://mega.ist.utl.pt/~ncpl/php_sockets_win.txt
 [2006-11-15 06:33 UTC] thessoro at gmail dot com
I think the existence of this bug should be mentioned in the documentation to prevent developers rely on PHP_NORMAL_READ. Although OS category is set to * i can only reproduce it in windows. I checked my script there too late.
So, as a script relying this feature is capable of making the entire socket extension useless on Windows, i think is important enough to mention it en the socket_read section of the manual. 

Thx,
 [2007-06-23 13:33 UTC] dinesh at dinsoft dot net
Hi all,

The bug is still there in: PHP 5.2.3 (cli) (built: May 31 2007 09:37:22) (binary zip release)

The initial bug report was posted on 26 Dec 2002 9:32am UTC, almost 5 years ago.

PHP_NORMAL_READ works well under *NIX, but the same scripts does not work on windows.

If the above patch is working, then it should be added in the binary release.

Thanks.
 [2007-06-23 22:23 UTC] dinesh at dinsoft dot net
Indeed, it works with :

	//m = fcntl(bsd_socket, F_GETFL);
	//if (m < 0) {
	//	return m;
	//}

	nonblock = 0;

So the fcntl() call makes it fail.

But this has the side effect of making the socket_read() call blocking even if the socket has been set to non blocking mode.

I will try to make a fully working patch with no side effect when I'll have some time, if no one else is wanting to solve this problem.

For the lambda users, here is a usuable dll built against PHP 5.2.3 :
 http://www.dinsoft.net/dev/php/php_sockets.dll

Regards,
 Dinesh Bolkensteyn
 [2007-07-17 20:57 UTC] jani@php.net
I have a patch prepared for this. Just waiting for dinesh at dinsoft dot net to test it for me. :)
 [2007-07-18 15:31 UTC] jani@php.net
The patch can be found at:

http://pecl.php.net/~jani/patches/bug_21197_socket_read.patch

 [2007-07-22 23:01 UTC] jani@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2018 The PHP Group
All rights reserved.
Last updated: Sun Sep 23 17:01:25 2018 UTC