1
0
mirror of https://github.com/danog/file.git synced 2025-01-22 13:21:13 +01:00

Fix write() truncation with ext-uv and ext-eio (#76)

This commit is contained in:
Daniil Gentili 2023-07-23 20:06:15 +02:00 committed by GitHub
parent 1c9f0ebdb2
commit c2313ea280
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 4 deletions

View File

@ -346,7 +346,7 @@ final class EioFilesystemDriver implements FilesystemDriver
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;

View File

@ -418,7 +418,7 @@ final class UvFilesystemDriver implements FilesystemDriver
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();
@ -454,8 +454,10 @@ final class UvFilesystemDriver implements FilesystemDriver
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,

View File

@ -4,6 +4,8 @@ namespace Amp\File\Test;
use Amp\ByteStream\ClosedException;
use Amp\File;
use Amp\File\Whence;
use function Amp\async;
abstract class FileTest extends FilesystemTest
@ -25,6 +27,35 @@ abstract class FileTest extends FilesystemTest
$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

View File

@ -506,6 +506,27 @@ abstract class FilesystemDriverTest extends FilesystemTest
$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();