php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #32858 Bug #25649 has crept back into PHP - Improper feof() handling under FreeBSD
Submitted: 2005-04-27 21:36 UTC Modified: 2005-08-06 01:00 UTC
Votes:3
Avg. Score:4.3 ± 0.5
Reproduced:2 of 3 (66.7%)
Same Version:1 (50.0%)
Same OS:2 (100.0%)
From: lew at mailduct dot com Assigned: wez
Status: No Feedback Package: Filesystem function related
PHP Version: 5.0.4, 4.3.10 OS: FreeBSD 4.11-REL
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [2005-04-27 21:36 UTC] lew at mailduct dot com
Description:
------------
In my prior bug report #25649 from September 2003, I pointed out a serious bug in how PHP handles FEOF under FreeBSD.  It was fixed by wez@php.net and committed.

This same problem (improper handling of feof() by PHP under FreeBSD) has now crept into current 4.3.X versions of PHP...

Problem:  Once set, the FEOF indicator is not properly cleared when more data is appended to a file that is opened for read by a PHP application.

Example:  Suppose I want to "tail" a file using PHP.  Once I hit the EOF, I will no longer be able to read data from that file even when another application appends to it.  This is not the correct behaviour for feof(), as illustrated by the prior fix done by wez@php.net.


Reproduce code:
---------------
--- program:
$fp = fopen( '/var/log/maillog','r' );
while( TRUE ) {
  $r = array( $fp );
  $n = stream_select( $r,$w=NULL,$e=NULL,30 );
  if( $n ) {
    echo fgets( $fp );
  }
}

--- feeder:
echo "This is a test..." >> /var/log/maillog


Expected result:
----------------
For as long as PROGRAM is running, each time I run
FEEDER I expect to see PROGRAM output "This is a test..."

but it does not, because once EOF is reached, it is not
properly reset upon more data being appended to the file.

See pr #25649 for historical info...

Actual result:
--------------
PROGRAM will read the contents of /var/log/maillog until it
reaches EOF, and will not output anything else, even if new
data is appeneded to the file.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-05-27 00:02 UTC] lew at mailduct dot com
I have now tested this using PHP 5.0.4 (cli), and the bug remains.  This bug was fixed by wez@php.net on Sep 2003, but has now crept back in to both versions 4 and 5 of PHP.

PHP is failing to clear the EOF indicator when reading a stream that would otherwise BLOCK if read.

--- quote (wez@php.net):
The PHP streams implementation uses the following logic
for determining the EOF status:

- after a read attempt, if no bytes were read OR
  (a read error occurred and the error != EWOULDBLOCK)
  --> set the EOF indicator
  otherwise, clear the EOF indicator [1]

- after a successful fseek(), clear the EOF indicator.

[1] - this step was missing and has just been comitted to
the CVS.

The feof() function call works like this:
- if stream buffer has data, return false
- otherwise, return the EOF indicator flag.

---endquote
 [2005-05-27 08:40 UTC] sniper@php.net
Assigning to Wez since he fixed it last time..

 [2005-07-28 01:46 UTC] lew at mailduct dot com
Bug is still present in latest snapshot of PHP.

Also... there seems to be at least one other bug report that is related to this problem.  See bug #32979.  The problem is
directly related (and caused) by faulty stream_select and stream_get_meta_data behaviour.

In summary:
1)  stream_select does not properly detect the presence of additional input data after it hits an EOF.  Neither does stream_get_meta_data.  They both continue to return EOF even for a stream that has new data (filestream, in my example).
2)  stream_select does not properly honor its timeout parameter.  If no data is available, the call should WAIT for the timeout period to expire before returning due to an EOF condition.  Instead, it always returns immediately with an EOF, making the timeout parameter pointless.
3)  stream_select does not properly emulate the select() system call, which would wait for a timeout if no more data were available (EOF)... in case more data did become available.

Please let me know how else I can help.  I'd like to get this recurring problem resolved once and for all.
 [2005-07-29 01:57 UTC] sniper@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5-win32-latest.zip


 [2005-08-06 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2008-02-11 14:05 UTC] sb1304 at hotmail dot com
Tested on Fedora4
Linux XXXX 2.6.11-1.1369_FC4smp #1 SMP Thu Jun 2 23:08:39 EDT 2005 i686 i686 i386 GNU/Linux

php 5.2.5 compiled without SSL (--openssl)

Reproduce code:

#!/usr/local/bin/php
<?php
$file = "/tmp/maillog";
$fp = @fopen($file, 'r');
if (!$fp)
 die ("Could not open $file");

while (true) {
   $r = array($fp);
   $n = stream_select($r, $w = null, $e = null, 30);
   if ($n) {
      echo fgets($fp);
   }
}

Still an issue in php5.2.x.

Stephen
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Mon Apr 21 14:02:18 2014 UTC