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

Multiple fopen on same file share the same pointer #129

Open
andrewnicols opened this Issue Jan 8, 2016 · 0 comments

Comments

Projects
None yet
2 participants
@andrewnicols

andrewnicols commented Jan 8, 2016

I just encountered this while having a look at adding exclusive lock support for #15/#126.

I've managed to get the lock side of things working (I think), but have discovered that when an fopen() multiple times on the same file, the same SeekableFileContent object is returned each time. As a result, the pointer and its position are shared, and successive reads against one file handle will move the pointer for all other file handles which have the file open.

Here's a simple testcase which demonstrates the issue:

/**
 * @test
 */
public function canGetOwnRead()
{
    $fp1 = fopen($this->baz2URL, 'rb');
    $fp2 = fopen($this->baz2URL, 'rb');
    $this->assertEquals('baz2', fread($fp1, 4096));
    $this->assertEquals('baz2', fread($fp2, 4096));
    fclose($fp1);
    fclose($fp2);
}

I've solved this hackily by storing the current position in the streamWrapper after move operations (read, write, seek, eof, etc.) and then restoring the location before a subsequent operation.

The more correct thing to do would be to do store the position in the fileContent, but that would likely mean huge API changes because most operations on the content currently don't require the resource requesting them -- none of the functions in src/main/php/org/bovigo/vfs/content/SeekableFileContent.php require the resource.
Another solution would be to full clone the content when it is retrieved - e.g. in src/main/php/org/bovigo/vfs/vfsStreamWrapper.php:

return unserialize(serialize(self::$root->getChild($path)));

However, this means that writes are not store against the VFS properly too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment