Req #39598 [Com]: error verification after fwrite()

2013-02-28 Thread gauthi...@php.net
Edit report at https://bugs.php.net/bug.php?id=39598edit=1

 ID: 39598
 Comment by: gauthi...@php.net
 Reported by:max at nucleus dot it
 Summary:error verification after fwrite()
 Status: Open
 Type:   Feature/Change Request
 Package:Feature/Change Request
 Operating System:   Linux
 PHP Version:5.2.0
 Block user comment: N
 Private report: N

 New Comment:

Here's a simple reproduce test case:

http://labs.silverorange.com/files/php-bug39598/php-bug-39598-test.phps

In this case, and EPIPE occurs. The fwrite call writes 0 bytes. No error code 
is 
available and no PHP error is raised.


Previous Comments:

[2006-11-22 22:53:31] max at nucleus dot it

Description:

The documentation states tha fwrite() returns false in 
case of error, but it doesn't do so if the actual write 
fails.
For example if I asynchronously write to a pipe (such as 
those obtained by proc_open()) I and the pipe is not ready 
or is broken, fwrite() returns 0.
This could be a correct behaviour it I had a way to 
determine the error.
The problem is that EAGAIN or EPIPE are completely 
impossible to determine and I can't know if I need to wait 
or I have to close the stream.
A possible solution would be to implement ferror() or 
errno.

Reproduce code:
---
$Proc = proc_open($Cmd, $Streams, $Pipes, $CWD, $Env);

stream_set_blocking($Pipes[0], 0);

$Result = fwrite($Pipes[0], test);

// If $Pipes[0] is not ready to receive data
// $Result is 0, but I can't know why.
// The real code I'm writing involves
// stream_select() and repeated reads and writes
// on multiple pipes.

Expected result:

fwrite() should return 0 when the stream is asynchrounous, 
the C write() returns 0 and errno is EAGAIN.
fwrite() should return false in all other cases where the 
C write() returns 0.

Alternatively a way to access ferror() or errno is needed.







-- 
Edit this bug report at https://bugs.php.net/bug.php?id=39598edit=1


Bug #52602 [Com]: fread is blocking even with the use of stream_select

2013-01-06 Thread gauthi...@php.net
Edit report at https://bugs.php.net/bug.php?id=52602edit=1

 ID: 52602
 Comment by: gauthi...@php.net
 Reported by:g at gsxm dot net
 Summary:fread is blocking even with the use of stream_select
 Status: Verified
 Type:   Bug
 Package:Sockets related
 Operating System:   Gentoo x86_64
 PHP Version:5.2.14
 Assigned To:cataphract
 Block user comment: N
 Private report: N

 New Comment:

This problem affected me while writing a WebSocket server in PHP. 
stream_select() returns streams ready for reading and fread() blocks when I try 
to read them. What is the point of stream_select() if it behaves like this? How 
are you supposed to write a blocking I/O loop?

My solution was to use stream_socket_recvfrom() and give up on implementing 
SSL/TLS for my server (making me a bit sad inside).

Since stream_select() returns the stream ready for reading, I would expect 
fread() to return the available bytes from the stream buffer in this case 
rather 
than blocking. See Bug 51056 for a long discussion on fread() behaviour with no 
conclusion.

Can some conclusion be reached for PHP? Is there any actual evidence of people 
writing their servers in a way where fixing fread() will break?


Previous Comments:

[2010-09-27 04:16:43] cataphr...@php.net

To sum up, the emulation behavior of stream_select is worse than useless:

* If using stream_socket_recvfrom(), the buffer will be bypassed anyway, so the 
emulation behavior won't kick in.
* If using fread() and there's something in the buffer, it will return the 
stream in the readfs set, which is documented to see if characters become 
available for reading (more precisely, to see if a read will not block [...]), 
but a subsequent fread call will nevertheless eventually block when trying to 
fill the buffer.


[2010-09-27 04:09:08] cataphr...@php.net

fread is not really adequate for this because of its buffering (see 
stream_socket_recvfrom()).

Since you are specifying a length of 128 to fread, if you receive say, a 138 
bytes long payload, the first call to fread will to read into the stream buffer 
the whole data, but will only return 128 bytes. The stream buffer remains with 
10 bytes, but the socket buffer will be empty. On the second call to fread, it 
will try to read into the stream buffer again, but this time the socket buffer 
is empty, so it will block until it can read another packet or until the 
timeout.

This appears, however, to be the desired behavior (perhaps fread could just 
return what it has in the buffer if it cannot read anything immediately, i.e., 
if it would otherwise block). So stream_select implements an emulation behavior 
that says the stream is readable without calling select if the there's data in 
the stream buffer. This is indeed odd, because the usual semantics of select 
are that it a read on a socket returned in the readfs set will not block.


[2010-08-14 05:35:51] g at gsxm dot net

Not sure why I did not think of this before, but perhaps only the stream-* 
functions works with stream_select


[2010-08-14 03:07:41] g at gsxm dot net

Description:

Using PHP CLI
Gentoo 64 bit box
PHP version 5.2.14
clean compile
Dual AMD Opteron 2212 CPU

Something is blocking in the code, it seems to be fread. I am sure this is not 
the expected result.

I greatly simplified the sample I included.

I can just put the socket/stream in non-blocking mode, but I would much prefer 
to use the code as I designed it. 

I have considered just using the socket functions in php or just writing the 
code in C.

Once in a great while it will resume after about thirty to sixty seconds. In 
non-blocking mode I have no issues. This is a php cli script that connects to 
another daemon running on the same machine, I am using this php script to parse 
data to place in a sql database.

Test script:
---
$sock=@fsockopen(localhost,,$errno,$errstr,3);
if (!$sock)
{ 
echo sock error.$crlf;
}

while(true)
{
$read=array($sock);
$write=NULL;
$except=NULL;
$status=@stream_select($read,$write,$except,1);
if ($status===false)
{
echo select error.$crlf;
exit();
}
if ($status0)
{
$data =  @fread($sock,128);
echo $data;
$out .= $data;
}

usleep(1);
}

Expected result:

The loop should run for eternity as expected.

Actual result:
--
The loop is blocked, I am presuming by fread due to a failure of the expected 
behavior of stream_select.






-- 
Edit this bug report at https

Bug #52602 [Com]: fread is blocking even with the use of stream_select

2013-01-06 Thread gauthi...@php.net
Edit report at https://bugs.php.net/bug.php?id=52602edit=1

 ID: 52602
 Comment by: gauthi...@php.net
 Reported by:g at gsxm dot net
 Summary:fread is blocking even with the use of stream_select
 Status: Verified
 Type:   Bug
 Package:Sockets related
 Operating System:   Gentoo x86_64
 PHP Version:5.2.14
 Assigned To:cataphract
 Block user comment: N
 Private report: N

 New Comment:

As another workaround, you can use the same chunk size in your read calls as 
the 
PHP stream chunk size. Then there is never buffered data that has not been 
consumed. In most cases the chunk size is 8192. In PHP 5.4 I think you can set 
the 
chunk size using stream_set_chunk_size().

This workaround allows you to continue using fread().


Previous Comments:

[2013-01-06 09:01:59] gauthi...@php.net

This problem affected me while writing a WebSocket server in PHP. 
stream_select() returns streams ready for reading and fread() blocks when I try 
to read them. What is the point of stream_select() if it behaves like this? How 
are you supposed to write a blocking I/O loop?

My solution was to use stream_socket_recvfrom() and give up on implementing 
SSL/TLS for my server (making me a bit sad inside).

Since stream_select() returns the stream ready for reading, I would expect 
fread() to return the available bytes from the stream buffer in this case 
rather 
than blocking. See Bug 51056 for a long discussion on fread() behaviour with no 
conclusion.

Can some conclusion be reached for PHP? Is there any actual evidence of people 
writing their servers in a way where fixing fread() will break?


[2010-09-27 04:16:43] cataphr...@php.net

To sum up, the emulation behavior of stream_select is worse than useless:

* If using stream_socket_recvfrom(), the buffer will be bypassed anyway, so the 
emulation behavior won't kick in.
* If using fread() and there's something in the buffer, it will return the 
stream in the readfs set, which is documented to see if characters become 
available for reading (more precisely, to see if a read will not block [...]), 
but a subsequent fread call will nevertheless eventually block when trying to 
fill the buffer.


[2010-09-27 04:09:08] cataphr...@php.net

fread is not really adequate for this because of its buffering (see 
stream_socket_recvfrom()).

Since you are specifying a length of 128 to fread, if you receive say, a 138 
bytes long payload, the first call to fread will to read into the stream buffer 
the whole data, but will only return 128 bytes. The stream buffer remains with 
10 bytes, but the socket buffer will be empty. On the second call to fread, it 
will try to read into the stream buffer again, but this time the socket buffer 
is empty, so it will block until it can read another packet or until the 
timeout.

This appears, however, to be the desired behavior (perhaps fread could just 
return what it has in the buffer if it cannot read anything immediately, i.e., 
if it would otherwise block). So stream_select implements an emulation behavior 
that says the stream is readable without calling select if the there's data in 
the stream buffer. This is indeed odd, because the usual semantics of select 
are that it a read on a socket returned in the readfs set will not block.


[2010-08-14 05:35:51] g at gsxm dot net

Not sure why I did not think of this before, but perhaps only the stream-* 
functions works with stream_select


[2010-08-14 03:07:41] g at gsxm dot net

Description:

Using PHP CLI
Gentoo 64 bit box
PHP version 5.2.14
clean compile
Dual AMD Opteron 2212 CPU

Something is blocking in the code, it seems to be fread. I am sure this is not 
the expected result.

I greatly simplified the sample I included.

I can just put the socket/stream in non-blocking mode, but I would much prefer 
to use the code as I designed it. 

I have considered just using the socket functions in php or just writing the 
code in C.

Once in a great while it will resume after about thirty to sixty seconds. In 
non-blocking mode I have no issues. This is a php cli script that connects to 
another daemon running on the same machine, I am using this php script to parse 
data to place in a sql database.

Test script:
---
$sock=@fsockopen(localhost,,$errno,$errstr,3);
if (!$sock)
{ 
echo sock error.$crlf;
}

while(true)
{
$read=array($sock);
$write=NULL;
$except=NULL;
$status=@stream_select($read,$write,$except,1);
if ($status===false)
{
echo select error.$crlf;
exit