ssh->setWindowSize($this->cols, $this->rows); $this->ssh->setTimeout(self::STARTUP_TIMEOUT_SECONDS); $this->ssh->enablePTY(); if ($this->ssh->exec($this->launchCommand, false) !== true) { throw new \RuntimeException('Unable to start remote terminal shell.'); } } public function read(): string { if (! $this->isAlive()) { return ''; } $output = ''; $this->ssh->setTimeout(self::READ_TIMEOUT_SECONDS); while (true) { $chunk = $this->ssh->read('', SSH2::READ_NEXT); if ($chunk === true) { if ($this->ssh->isTimeout()) { break; } $this->closed = true; break; } if (! is_string($chunk) || $chunk === '') { break; } $output .= $chunk; } return $output; } public function write(string $input): void { if ($input === '' || ! $this->isAlive()) { return; } $this->ssh->write($input); } public function resize(int $cols, int $rows): void { // phpseclib applies the PTY size during shell creation; runtime resize is left as a no-op // to avoid injecting visible shell commands into the user session. } public function isAlive(): bool { return ! $this->closed && $this->ssh->isConnected(); } public function close(): void { if ($this->ssh->isConnected()) { try { $this->ssh->write("exit\n"); } catch (\Throwable) { // Ignore shutdown write failures. } $this->ssh->disconnect(); } $this->closed = true; } }