|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2003-02-21 13:58 UTC] php at codewhore dot org
In PHP:
<?php
$fp = fopen('./foo', 'w+');
fwrite($fp, 'quxbar', 6);
fseek($fp, 3, SEEK_SET);
fread($fp, 1);
fseek($fp, 4, SEEK_SET);
fwrite($fp, '!', 1);
fseek($fp, 0, SEEK_SET);
$buf = fread($fp, 4095);
echo "$buf\n";
?>
In C:
#include <stdio.h>
int main()
{
static char buf[4096];
FILE *f = fopen("./foo", "w+");
fwrite("quxbar", 6, 1, f);
fseek(f, 3, SEEK_SET);
fread(&buf, 1, 1, f);
fseek(f, 4, SEEK_SET);
fwrite("!", 1, 1, f);
fseek(f, 0, SEEK_SET);
fread(&buf, 4095, 1, f);
printf("%s\n", buf);
return 0;
}
The PHP version outputs 'quxbar!.
The C version outputs 'quxb!r'.
In fact, for any PHP code of the structure:
<?php
fseek($fp, $x, SEEK_SET);
fread($fp, $n);
fseek($fp, $y, SEEK_SET);
fwrite($fp, '!', 1);
?>
the data from the fwrite always gets written to the end of the stream when $x < $y and $n is exactly 1. I can reproduce this with different whence parameters, but it seems to only happen with a seek followed by a single-byte read.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Nov 16 22:00:01 2025 UTC |
I'm still mostly lost, but commenting out the following segment of code fixes the problem for the test case. Obviously this isn't the solution, but I think I have it narrowed down to _php_stream_seek thinking that the underlying file position matches the seek offset when it doesn't in reality. PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC) { /* not moving anywhere */ #if 0 if ((offset == 0 && whence == SEEK_CUR) || (offset == stream->position && whence == SEEK_SET)) return 0; #endifFWIW, the problem also occurs in the following piece of code: <?php $fp = fopen('./foo', 'w+'); fwrite($fp, 'quxbar', 6); fseek($fp, 3, SEEK_SET); fread($fp, 1); fwrite($fp, '!', 1); fseek($fp, 0, SEEK_SET); $buf = fread($fp, 4095); echo "$buf\n"; ?> There's no fseek() between the fread() and fwrite(), so my previous theory seems to be quite wrong. I'll do more digging as time permits...