diff --git a/lib/EioDriver.php b/lib/EioDriver.php index e3e6d3f..5efc511 100644 --- a/lib/EioDriver.php +++ b/lib/EioDriver.php @@ -296,10 +296,19 @@ class EioDriver implements Driver { $this->poll->listen($deferred->promise()); $priority = \EIO_PRI_DEFAULT; - \eio_readlink($path, $priority, [$this, "onGenericResult"], $deferred); + \eio_readlink($path, $priority, [$this, "onReadlink"], $deferred); return $deferred->promise(); } + + private function onReadlink($deferred, $result, $req) { + if ($result === -1) { + $deferred->fail(new FilesystemException(\eio_get_last_error($req))); + } else { + $deferred->resolve($result); + } + } + private function onGenericResult($deferred, $result, $req) { if ($result === -1) { $deferred->fail(new FilesystemException(\eio_get_last_error($req))); diff --git a/lib/UvDriver.php b/lib/UvDriver.php index 0783365..571f898 100644 --- a/lib/UvDriver.php +++ b/lib/UvDriver.php @@ -320,8 +320,12 @@ class UvDriver implements Driver { $deferred = new Deferred; $this->poll->listen($deferred->promise()); - \uv_fs_readlink($this->loop, $path, function ($fh) use ($deferred) { - $deferred->resolve((bool) $fh); + \uv_fs_readlink($this->loop, $path, function ($fh, $target) use ($deferred) { + if (!(bool) $fh) { + $deferred->fail(new FilesystemException("Could not read symbolic link")); + } + + $deferred->resolve($target); }); return $deferred->promise(); diff --git a/test/DriverTest.php b/test/DriverTest.php index 7523e9b..9f07760 100644 --- a/test/DriverTest.php +++ b/test/DriverTest.php @@ -57,6 +57,43 @@ abstract class DriverTest extends TestCase { }); } + public function testReadlink() { + $this->execute(function () { + $fixtureDir = Fixture::path(); + + $original = "{$fixtureDir}/small.txt"; + $link = "{$fixtureDir}/symlink.txt"; + \symlink($original, $link); + + $this->assertSame($original, yield File\readlink($link)); + }); + } + + public function readlinkPathProvider() { + return [ + 'nonExistingPath' => [function () { + return Fixture::path() . '/' . uniqid(); + }], + 'notLink' => [function () { + return Fixture::path(); + }], + ]; + } + + /** + * @dataProvider readlinkPathProvider + * @expectedException \Amp\File\FilesystemException + * + * @param \Closure $linkResolver + */ + public function testReadlinkError(\Closure $linkResolver) { + $this->execute(function () use ($linkResolver) { + $link = $linkResolver(); + + yield File\readlink($link); + }); + } + public function testLstat() { $this->execute(function () { $fixtureDir = Fixture::path(); diff --git a/test/UvDriverTest.php b/test/UvDriverTest.php index e2e6f33..47bf566 100644 --- a/test/UvDriverTest.php +++ b/test/UvDriverTest.php @@ -22,4 +22,13 @@ class UvDriverTest extends DriverTest { asyncCall($cb); }); } + + /** + * @dataProvider readlinkPathProvider + * + * @param \Closure $linkResolver + */ + public function testReadlinkError(\Closure $linkResolver) { + $this->markTestSkipped('UvDriver Test Skipped: Causes Crash'); + } }