-
Notifications
You must be signed in to change notification settings - Fork 102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot read and write to open streams on the same file #222
Comments
Possibly relevant is that calling $file = vfsStream::newFile('test')->at($root);
$w = fopen($file->url(), 'w');
$r = fopen($file->url(), 'r');
fwrite($w, "hello\n");
echo fgets($r);
# 'hello'
echo feof($r) ? "EOF\n" : "Not EOF\n";
# 'EOF' vs $w = fopen('/tmp/something', 'w');
$r = fopen('/tmp/something', 'r');
fwrite($w, "hello\n");
echo fgets($r);
# 'hello'
echo feof($r) ? "EOF\n" : "Not EOF\n";
# 'Not EOF'
echo fgets($r);
# empty
echo feof($r) ? "EOF\n" : "Not EOF\n";
# 'EOF'
# subsequent calls to fgets($r) will return empty, even if more data has been written |
We are currently working on a fix in #220 this functionality has landed in our master branch. Since a large rename is currently in progress it might not be very convenient to use the version in master right now. Sorry I missed something in your report. It looks like the implementation is not fully correct to mimic the real files. |
I believe the test cases in #223 reproduce my issue and describe the behaviour that would match native files. |
👍 Those tests are great. Hopefully #221 can get finished soon, as it restructures a lot of things that would likely cause a lot of conflicts if more than a couple lines need to be changed. |
I just played around with that, thanks for providing the test. It seems like the fault isn't in vfsStream. To be more precise: even if |
There's a workaround, though: you can change the default value |
Unfortunately, |
Ah, I think I see what's happening then.
This process is failing with vfsStream for two reasons:
So in my example, PHP asks for "up to 8192 bytes", and gets the full file content. The stream should return the contents of the file, and remain open with offset=size, eof=false until the next read. |
…read This doesn't correctly handle manual seeks, which should somehow reset the EOF pointer. There are also lots of failing tests which are asserting behaviour which doesn't match the native file handler.
…read This doesn't correctly handle manual seeks, which should somehow reset the EOF pointer. There are also lots of failing tests which are asserting behaviour which doesn't match the native file handler.
The EOF flag on native file streams is only set after reading *past* the end of the buffer, never on open or seek. I believe all the failing tests here are asserting behaviour that doesn't match the native file handler.
Testing with normal files show that fread() does not progress the pointer beyond the end of the file, and a read *beyond* the file size is required before feof() returns true.
Based on the above, I have raised a PR which tracks offset and EOF separately: https://github.com/bovigo/vfsStream/pull/224/files The possibly non-obvious part is that |
The EOF flag on native file streams is only set after reading *past* the end of the buffer, never on open or seek. I believe all the failing tests here are asserting behaviour that doesn't match the native file handler.
The EOF flag on native file streams is only set after reading *past* the end of the buffer, never on open or seek. I believe all the failing tests here are asserting behaviour that doesn't match the native file handler.
Great find! Although I'm a bit surprised that it took more than 12 years to find that my initial eof implementation is flawed. 😁 |
Firstly, thanks to the creators and maintainers of this project, it's a really useful tool.
I had a scenario where I wanted to mock a streamed input (in the real application, it will open
php://input
), so tried to open the same file twice, once for writing (in the test) and once for reading (in the tested code).Any data written before the first read shows up fine on the read handle, but subsequent writes are not reflected. Rewinding the read handle works as expected, i.e. the whole contents of the file are visible on subsequent reads.
I suspect this is related to #129; testing before and after the patch in #220 shows that previously even the first read came back empty.
Simple reproduction script:
For comparison, if I change the
fopen
calls to reference a real file, the "hello again" gets echoed as I expected.The text was updated successfully, but these errors were encountered: