diff --git a/src/TelnetClient.php b/src/TelnetClient.php index 8ca770f..bd0ffa7 100644 --- a/src/TelnetClient.php +++ b/src/TelnetClient.php @@ -167,6 +167,21 @@ public function getSocket() return $this->socket; } + /** + * @param float $timeout + */ + public function setReadTimeout($timeout) + { + if (!$this->socket) { + throw new TelnetException('cannot set read timeout, socket does not exist (call connect() first)'); + } + + $sec = floor($timeout); + $usec = round(fmod($timeout, 1) * 1000000); + + $this->socket->setOption(SOL_SOCKET, SO_RCVTIMEO, ['sec' => $sec, 'usec' => $usec]); + } + /** * @param string $command * @param string $prompt diff --git a/tests/unit/TelnetClientTest.php b/tests/unit/TelnetClientTest.php index 7449645..97ed9bd 100644 --- a/tests/unit/TelnetClientTest.php +++ b/tests/unit/TelnetClientTest.php @@ -291,4 +291,46 @@ public function testFactory() $client = TelnetClient::factory(); $this->assertInstanceOf(TelnetClient::class, $client); } + + /** + * @dataProvider setReadTimeoutDataProvider + * @param float $timeout + * @param int $expectedSec + * @param int $expectedUsec + */ + public function testSetReadTimeout($timeout, $expectedSec, $expectedUsec) + { + $client = m::mock(TelnetClient::class)->makePartial(); + + $socket = m::mock(Socket::class) + ->shouldReceive('setOption') + ->with(SOL_SOCKET, SO_RCVTIMEO, ['sec' => $expectedSec, 'usec' => $expectedUsec]) + ->shouldReceive('close') + ->getMock(); + + $client->setSocket($socket); + + $client->setReadTimeout($timeout); + } + + /** + * @return mixed[] + */ + public function setReadTimeoutDataProvider() + { + return [ + [1, 1, 0], + [0.5, 0, 500000], + [2.345, 2, 345000], + ]; + } + + public function testSetReadTimeoutException() + { + $this->setExpectedException(TelnetExceptionInterface::class); + + $client = m::mock(TelnetClient::class)->makePartial(); + + $client->setReadTimeout(1); + } }