Skip to content

Commit

Permalink
Add timeout and error handling to getStdIn method (#25)
Browse files Browse the repository at this point in the history
* Add timeout and error handling to getStdIn method

The getStdIn method in CliCommand.php now accepts a timeout parameter and includes error handling mechanisms for reading from STDIN. It implements a timeout during read operations and throws exceptions if the read operation fails or is timed out, enhancing robustness and failure mode handling.

* Improve STDIN reading in getStdIn method

The getStdIn function in CliCommand.php has been updated to better handle STDIN input. It now incorporates timeout and error handling features. This should enhance its robustness, particularly in case of read operation hurdles or timeout issues.
  • Loading branch information
SmetDenis committed Jan 28, 2024
1 parent d0cb410 commit 7577c4d
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
2 changes: 1 addition & 1 deletion demo/Commands/DemoOptionsStrictTypes.php
Expand Up @@ -179,7 +179,7 @@ protected function executeAction(): int

// //////////////////////////////////////// Standard input
// echo " Qwerty 123 " | php ./my-app examples:agruments
self::getStdIn(); // " Qwerty 123 \n"
$this->_('STDIN: "' . self::getStdIn() . '"'); // " Qwerty 123 \n"

// Default success exist code is "0". Max value is 255.
return self::SUCCESS;
Expand Down
26 changes: 22 additions & 4 deletions src/CliCommand.php
Expand Up @@ -429,15 +429,33 @@ protected function askOption(string $question, array $options, null|float|int|st
);
}

protected static function getStdIn(): ?string
/**
* Reads input from STDIN with an optional timeout.
*
* @param int $timeout the timeout value in seconds (default: 5)
* @return null|string the string read from STDIN, or null if an error occurred
* @throws Exception if there was an error reading from STDIN or if the read operation timed out
*/
protected static function getStdIn(int $timeout = 5): ?string
{
static $result; // It can be read only once, so we save result as internal varaible
static $result; // It can be read only once, so we save result as internal variable

if ($result === null) {
$result = '';

while (!\feof(\STDIN)) {
$result .= \fread(\STDIN, 1024);
$read = [\STDIN];
$write = [];
$except = [];
$streamCount = \stream_select($read, $write, $except, $timeout);

if ($streamCount > 0) {
while ($line = \fgets(\STDIN, 1024)) {
$result .= $line;
}
}

if ($result === '') {
cli("Reading from STDIN timed out ({$timeout} seconds)", OutLvl::WARNING);
}
}

Expand Down

0 comments on commit 7577c4d

Please sign in to comment.