Skip to content

Multiple fopen on same file share the same pointer #129

@andrewnicols

Description

@andrewnicols

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions