Repository: symfony/symfony
File: src/Symfony/Component/Console/Helper/QuestionHelper.php (PHP)

Code before:
    private function isInteractiveInput($inputStream): bool
    {
        if ('php://stdin' !== (stream_get_meta_data($inputStream)['uri'] ?? null)) {
            return false;
        }

        if (isset(self::$stdinIsInteractive)) {
            return self::$stdinIsInteractive;
        }

        return self::$stdinIsInteractive = @stream_isatty(fopen('php://stdin', 'r'));
    }

    /**
     * Reads one or more lines of input and returns what is read.
     *
     * @param resource $inputStream The handler resource
     * @param Question $question    The question being asked
     */
    private function readInput($inputStream, Question $question): string|false
    {
        if (null !== $question->getTimeoutSeconds()) {
            $streamType = stream_get_meta_data($inputStream)['stream_type'] ?? null;

            if ('MEMORY' === $streamType) {
                throw new RuntimeException('Using question timeout is incompatible with memory streams.');
            }

            $read = [$inputStream];
            $write = null;
            $except = null;
            $changedStreams = stream_select($read, $write, $except, $question->getTimeoutSeconds());

            if (0 === $changedStreams) {
                throw new MissingInputException('Timed out.');
            }
        }

        if (!$question->isMultiline()) {
            $cp = $this->setIOCodepage();
            $ret = fgets($inputStream, 4096);

            return $this->resetIOCodepage($cp, $ret);
        }

        $multiLineStreamReader = $this->cloneInputStream($inputStream);
        if (null === $multiLineStreamReader) {
            return false;
        }

        $ret = '';

Review comment (suggestion):
Maybe, we could allow timeout only when `$this->isInteractiveInput($inputStream)` returns `true`...

Code after:
    private function isInteractiveInput($inputStream): bool
    {
        if ('php://stdin' !== (stream_get_meta_data($inputStream)['uri'] ?? null)) {
            return false;
        }

        if (isset(self::$stdinIsInteractive)) {
            return self::$stdinIsInteractive;
        }

        return self::$stdinIsInteractive = @stream_isatty(fopen('php://stdin', 'r'));
    }

    /**
     * Reads one or more lines of input and returns what is read.
     *
     * @param resource $inputStream The handler resource
     * @param Question $question    The question being asked
     */
    private function readInput($inputStream, Question $question): string|false
    {
        if (null !== $question->getTimeout() && $this->isInteractiveInput($inputStream)) {
            $read = [$inputStream];
            $write = null;
            $except = null;
            $timeoutSeconds = $question->getTimeout();
            $changedStreams = stream_select($read, $write, $except, $timeoutSeconds);

            if (0 === $changedStreams) {
                throw new MissingInputException(\sprintf('Timed out after waiting for input for %d second%s.', $timeoutSeconds, 1 === $timeoutSeconds ? '' : 's'));
            }
        }

        if (!$question->isMultiline()) {
            $cp = $this->setIOCodepage();
            $ret = fgets($inputStream, 4096);

            return $this->resetIOCodepage($cp, $ret);
        }

        $multiLineStreamReader = $this->cloneInputStream($inputStream);
        if (null === $multiLineStreamReader) {
            return false;
        }

        $ret = '';
        $cp = $this->setIOCodepage();
        while (false !== ($char = fgetc($multiLineStreamReader))) {
            if ("\x4" === $char || \PHP_EOL === "{$ret}{$char}") {
                break;
            }