php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #40566 Fgets screws up php on a nonblocked socket
Submitted: 2007-02-20 20:36 UTC Modified: 2007-02-21 00:05 UTC
From: myself at ligesh dot com Assigned:
Status: Not a bug Package: Sockets related
PHP Version: 5.2.1 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: myself at ligesh dot com
New email:
PHP Version: OS:

 

 [2007-02-20 20:36 UTC] myself at ligesh dot com
Description:
------------
 If i do an fgets on a socket that has been noblocked using stream_set_blocking($fp, false);, then php goes into a loop. 

 stream_set_blocking($socket, false);

 fgets($socket, 1024);

 Instead of returning instantly at teh fgets, php goes into an internal loop. The strace is:

--------------
read(4, 0x98b9180, 5)                   = -1 EAGAIN (Resource temporarily unavailable)
 Continiously repeated.
--------------------

 This is a very nasty bug, and i am really suprised how it got in there. It was working fine with 5.2.0, but i made a mistake of upgrading to 5.2.1 and my major program has completely broken down.


 

 

Reproduce code:
---------------
----------
$fd =  stream_socket_client("ssl://$serv_addr:$serv_port")
stream_set_blocking($fd, false);
 fgets($fd, 1024);
-------------


Expected result:
----------------
 Return immediately.

Actual result:
--------------
 Goes into a manic loop of read returning einval.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-02-20 20:45 UTC] tony2001@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.

Cannot reproduce.
 [2007-02-20 20:59 UTC] myself at ligesh dot com
Ok, Below is the code that will produce it. The fread should return immediately, and the php should print the message, and then sleep for 1 second, and continue. But instead, u will see php will go into manic loop, INSIDE the fgets, and will not return. There is no problem if it is in blocking mode. The function will not return, but it doesn't become crazy. The version is php 5.2.1.

<?php 

$fd =  stream_socket_client("ssl://localhost:443");
stream_set_blocking($fd, false);

while (true) {
	$res = fread($fd, 1024);
	print("Got something $res\n");
	print("\n");
	sleep(1);
}
 [2007-02-20 21:05 UTC] myself at ligesh dot com
OK, i checked with 5.2.0 and it works as expected. Also note that i am using "-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" at compile time. Though i don't how this can affect the socket operations. Also the php-5.20 which is working fine, is also compiled with LARGEFILE_SOURCE. So it is something in php 5.2.1 that's causing teh problem.
 [2007-02-20 21:15 UTC] tony2001@php.net
I see a lot of "Get something".
 [2007-02-20 21:27 UTC] myself at ligesh dot com
Yeah, That's the correct behaviour. Below are my compile time options. Please note that php-5.2.0 compiled with the same options works fine.

-------------------
sh ./configure --prefix=/usr/local/ext/php --with-config-file-path=/usr/local/ext/php/etc  --enable-force-cgi-redirect --disable-debug --enable-pic --disable-rpath --enable-cgi --enable-inline-optimization --with-db4=/usr    --enable-posix  --with-gettext --with-gmp --with-iconv  --with-sqlite --with-openssl --with-regex=system  --with-expat-dir=/usr --with-dom=shared,/usr --with-dom-xslt=/usr --with-dom-exslt=/usr --with-pcre-regex --with-zlib --enable-simplexml  --with-layout=GNU  --enable-bcmath --enable-exif --enable-ftp --enable-magic-quotes --enable-safe-mode --enable-sockets  --enable-sysvsem --enable-sysvshm --enable-discard-path --enable-track-vars  --enable-trans-sid  --without-oci8 --with-kerberos    --with-mysql=shared,/usr --with-pgsql=shared --enable-memory-limit  --enable-bcmath --enable-shmop --enable-dbx --enable-dio  --enable-mcal  --enable-mbstring  --enable-mbstr-enc-trans --enable-mbregex  --with-curl=/usr --enable-pcntl 
make EXTRA_CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
 [2007-02-20 21:32 UTC] tony2001@php.net
Please reduce this list of options to the minimum required to replicate the problem.
 [2007-02-20 21:36 UTC] myself at ligesh dot com
Hello,

It will take me more than a day to compile different versions of php and test it, since i have to test many permustions of compile time options and  each compile will take 1 to 2 hours. in your case, you can just use the compile flags i have provided and see if it is triggering the bug. This is a critical error, and i am sure a lot of people's php is silently failing.
 [2007-02-20 22:00 UTC] tony2001@php.net
As I have already said it works perfectly fine here.
With any options I still see lots of "Get something".
 [2007-02-20 23:55 UTC] myself at ligesh dot com
OK, i guess, it is one of those truly magical phenomena that one encounters once in a while. I will consult the harry potter books and reply back. I rewrote the software using socket_select with a timeout rather than non block, it has become irrelevant as far as i am concerned. But if possible just see if someone can replicate the problem. 

 Thanks.
 [2007-02-21 00:05 UTC] tony2001@php.net
Please reopen the report when/if you have more information as to how to replicate it.
Thanks.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 18:01:28 2024 UTC