Skip to content

Commit

Permalink
Fix ResourceOutputStream closed detection
Browse files Browse the repository at this point in the history
The previous mechanism with feof doesn't work for systemd launched processes.

Fixes #58.
  • Loading branch information
kelunik committed May 8, 2019
1 parent d5cd42a commit 90e8097
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
9 changes: 7 additions & 2 deletions lib/ResourceOutputStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public function __construct($stream, int $chunkSize = null)
continue;
}

if (!\is_resource($stream) || @\feof($stream)) {
if (!\is_resource($stream)) {
throw new StreamException("The stream was closed by the peer");
}

Expand All @@ -87,6 +87,11 @@ public function __construct($stream, int $chunkSize = null)

// Broken pipes between processes on macOS/FreeBSD do not detect EOF properly.
if ($written === 0) {
$metaData = @\stream_get_meta_data($stream);
if (!\is_resource($stream) || ($metaData && $metaData['eof'])) {
throw new StreamException("The stream was closed by the peer");
}

if ($emptyWrites++ > self::MAX_CONSECUTIVE_EMPTY_WRITES) {
$message = "Failed to write to stream after multiple attempts";
if ($error = \error_get_last()) {
Expand Down Expand Up @@ -179,7 +184,7 @@ private function send(string $data, bool $end = false): Promise
return new Success(0);
}

if (!\is_resource($this->resource) || @\feof($this->resource)) {
if (!\is_resource($this->resource)) {
return new Failure(new StreamException("The stream was closed by the peer"));
}

Expand Down
6 changes: 3 additions & 3 deletions test/ResourceOutputStreamTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function testBrokenPipe()
\fclose($b);

$this->expectException(StreamException::class);
$this->expectExceptionMessage("The stream was closed by the peer");
$this->expectExceptionMessage("Failed to write to stream after multiple attempts; fwrite(): send of 6 bytes failed with errno=32 Broken pipe");
wait($stream->write("foobar"));
}

Expand All @@ -60,7 +60,7 @@ public function testClosedRemoteSocket()
\fclose($b);

$this->expectException(StreamException::class);
$this->expectExceptionMessage("The stream was closed by the peer");
$this->expectExceptionMessage("Failed to write to stream after multiple attempts; fwrite(): send of 6 bytes failed with errno=32 Broken pipe");

// The first write still succeeds somehow...
wait($stream->write("foobar"));
Expand Down Expand Up @@ -88,7 +88,7 @@ public function testClosedRemoteSocketWithFork()
\fclose($b);

$this->expectException(StreamException::class);
$this->expectExceptionMessage("The stream was closed by the peer");
$this->expectExceptionMessage("Failed to write to stream after multiple attempts; fwrite(): send of 6 bytes failed with errno=32 Broken pipe");

try {
// The first write still succeeds somehow...
Expand Down

0 comments on commit 90e8097

Please sign in to comment.