php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #10236 ftruncate problem
Submitted: 2001-04-08 21:05 UTC Modified: 2001-09-09 06:13 UTC
From: nissler at fdns-services dot de Assigned:
Status: Not a bug Package: Filesystem function related
PHP Version: 4.0.4 OS: Linux 2.2.5 / glibc 2.0.7
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: nissler at fdns-services dot de
New email:
PHP Version: OS:

 

 [2001-04-08 21:05 UTC] nissler at fdns-services dot de
I've had a little problem with ftruncate, here is a sample
script that misbehaves for me:

<?
function movedata ($fd, $count)
{
  $p = ftell($fd);
  if ( $count < 0 )
  {
    $p += $count;
  }
  $r = 1024;
  if ($count > 0 && $r < $count)
  {
    $r = $count;
  }
  else if ($count < 0 && $r < -$count)
  {
    $r = -$count;
  }
  $c1 = strlen($buf1 = fread($fd,$r));
  $eof = false;
  while ( !$eof )
  {
    $c2 = strlen($buf2 = fread($fd,$r));
    $eof = feof($fd);
    fseek($fd,-$c2-$c1+$count,SEEK_CUR);
    fwrite($fd,$buf1,$c1);
    fseek($fd,$c2-$count,SEEK_CUR);
    $buf1 = $buf2;
    $c1 = $c2;
  }
  fseek($fd,-$c1+$count,SEEK_CUR);
  fwrite($fd,$buf1,$c1);
  ftruncate($fd,ftell($fd));
  // **** Uncomment the fflush to get it working ****
//  fflush($fd);
  fseek($fd,$p,SEEK_SET);
};

header("Content-type: text/plain");

$fd = fopen('test','w+') or die("Couldn't open file.\n");
$file = <<<EOL
<aaaaaa>
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
</aaaaaa>
<bbbbb>
BBBBBBBBBB
</bbbbb>

EOL;
fputs($fd,$file);
fclose($fd);

$fd = fopen('test','r+') or die("Couldn't open file.\n");
$str =
"CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n";
fseek($fd,9+strlen($str),SEEK_SET);
movedata($fd,-strlen($str));
movedata($fd,strlen($str));
fseek($fd,9,SEEK_SET);
fputs($fd,$str);
fseek($fd,0,SEEK_SET);
fpassthru($fd);

?>

Here is the output:
<aaaaaa>
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
</aaaaaa>
<bbbbb>
BBBBBBBBBB
</bbbbb>
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
</aaaaaa>
<bbbbb>
BBBBBBBBBB
</bbbbb>

I think it should be:

<aaaaaa>
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
</aaaaaa>
<bbbbb>
BBBBBBBBBB
</bbbbb>


What I found is that the second movedata call doesn't work
the way I want it to. As you can see in the output there is
some garbage data that seems to come from the first movedata
call.
I'm not really sure if the thing I found is really a bug,
since the above code might also be buggy. Furthermore this
is really the only case I found to reproduce the problem
(simpler test programs worked fine). The problem might also
be caused by linux/glibc (I know the given versions are
quite old, I'll upgrade soon :-)).
I think there might be a problem with buffered i/o so that
eof doesn't know about the new file size set by ftruncate
since the libc buffered i/o layered isn't flushed and php
source only calls fileno to find out the fd, but the stream
isn't flushed, and the ftruncate libc call isn't in sync
with the buffered i/o layer.
I think php function ftruncate should do a fflush libc call
before doing the ftruncate library call, so that everything
works fine and the php programmer won't have to care about that.

Have fun.

Mattias Nissler (nissler@fdns-services.de)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-09-09 06:13 UTC] sterling@php.net
wow :)

No this is not a bug... and no we shouldn't be doing an
fflush(), you can do a fflush() in the PHP code if you want.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Oct 31 23:01:28 2024 UTC