Skip to content

Commit

Permalink
Fix write() truncation with ext-uv and ext-eio (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
danog authored Jul 23, 2023
1 parent 1c9f0eb commit c2313ea
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/Driver/EioFilesystemDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ public function read(string $path): string

public function write(string $path, string $contents): void
{
$flags = \EIO_O_RDWR | \EIO_O_CREAT;
$flags = \EIO_O_RDWR | \EIO_O_CREAT | \EIO_O_TRUNC;
$mode = \EIO_S_IRUSR | \EIO_S_IWUSR | \EIO_S_IXUSR;
$priority = \EIO_PRI_DEFAULT;

Expand Down
8 changes: 5 additions & 3 deletions src/Driver/UvFilesystemDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ public function read(string $path): string

public function write(string $path, string $contents): void
{
$flags = \UV::O_WRONLY | \UV::O_CREAT;
$flags = \UV::O_WRONLY | \UV::O_CREAT | \UV::O_TRUNC;
$mode = \UV::S_IRWXU | \UV::S_IRUSR;

$this->poll->listen();
Expand Down Expand Up @@ -454,8 +454,10 @@ private function parseMode(string $mode): int
return match ($mode) {
"r" => \UV::O_RDONLY,
"r+" => \UV::O_RDWR,
"c", "w" => \UV::O_WRONLY | \UV::O_CREAT,
"c+", "w+" => \UV::O_RDWR | \UV::O_CREAT,
"c" => \UV::O_WRONLY | \UV::O_CREAT,
"w" => \UV::O_WRONLY | \UV::O_CREAT | \UV::O_TRUNC,
"c+" => \UV::O_RDWR | \UV::O_CREAT,
"w+" => \UV::O_RDWR | \UV::O_CREAT | \UV::O_TRUNC,
"a" => \UV::O_WRONLY | \UV::O_CREAT | \UV::O_APPEND,
"a+" => \UV::O_RDWR | \UV::O_CREAT | \UV::O_APPEND,
"x" => \UV::O_WRONLY | \UV::O_CREAT | \UV::O_EXCL,
Expand Down
31 changes: 31 additions & 0 deletions test/FileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use Amp\ByteStream\ClosedException;
use Amp\File;
use Amp\File\Whence;

use function Amp\async;

abstract class FileTest extends FilesystemTest
Expand All @@ -25,6 +27,35 @@ public function testWrite(): void
$this->assertSame("foobar", $contents);

$handle->close();

$handle = $this->driver->openFile($path, "c+");
$handle->seek(0, Whence::End);
$this->assertSame(6, $handle->tell());

$handle->close();
}

public function testWriteTruncate(): void
{
$path = Fixture::path() . "/write";
$handle = $this->driver->openFile($path, "c+");
$this->assertSame(0, $handle->tell());

$handle->write("foo");
$handle->write("bar");
$handle->seek(0);
$contents = $handle->read();
$this->assertSame(6, $handle->tell());
$this->assertTrue($handle->eof());
$this->assertSame("foobar", $contents);

$handle->close();

$handle = $this->driver->openFile($path, "w+");
$handle->seek(0, Whence::End);
$this->assertSame(0, $handle->tell());

$handle->close();
}

public function testEmptyWrite(): void
Expand Down
21 changes: 21 additions & 0 deletions test/FilesystemDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,27 @@ public function testTouch(): void
$this->assertTrue($newStat["mtime"] > $oldStat["mtime"]);
}

/**
* @group slow
*/
public function testWrite(): void
{
$fixtureDir = Fixture::path();

$contents1 = "write test longer";
$contents2 = "write test";
$path = "{$fixtureDir}/write.txt";

$this->driver->write($path, $contents1);
$this->assertSame($contents1, $this->driver->read($path));

$this->driver->write($path, $contents2);
$this->assertSame($contents2, $this->driver->read($path));

$this->driver->write($path, $contents1);
$this->assertSame($contents1, $this->driver->read($path));
}

public function testTouchFailsOnNonexistentPath(): void
{
$fixtureDir = Fixture::path();
Expand Down

0 comments on commit c2313ea

Please sign in to comment.