8000 [Console] fix restoring stty mode on CTRL+C · symfony/symfony@15a32aa · GitHub
[go: up one dir, main page]

Skip to content

Commit 15a32aa

Browse files
[Console] fix restoring stty mode on CTRL+C
1 parent 6cdfd71 commit 15a32aa

File tree

3 files changed

+32
-6
lines changed

3 files changed

+32
-6
lines changed

src/Symfony/Component/Console/Application.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,7 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI
957957
$event = new ConsoleSignalEvent($command, $input, $output, $signal);
958958

959959
$this->signalRegistry->register($signal, function ($signal, $hasNext) use ($event) {
960+
Terminal::restoreSttyMode();
960961
$this->dispatcher->dispatch($event, ConsoleEvents::SIGNAL);
961962

962963
// No more handlers, we try to simulate PHP default behavior

src/Symfony/Component/Console/Helper/QuestionHelper.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
247247
$matches = $autocomplete($ret);
248248
$numMatches = \count($matches);
249249

250-
$sttyMode = shell_exec('stty -g');
250+
$sttyMode = Terminal::backupSttyMode();
251251

252252
// Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead)
253253
shell_exec('stty -icanon -echo');
@@ -257,11 +257,17 @@ private function autocomplete(OutputInterface $output, Question $question, $inpu
257257

258258
// Read a keypress
259259
while (!feof($inputStream)) {
260+
do {
261+
// Give signal handlers a chance to run
262+
$r = [$inputStream];
263+
$w = [];
264+
} while (0 === @stream_select($r, $w, $w, 0, 100));
265+
260266
$c = fread($inputStream, 1);
261267

262268
// as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false.
263269
if (false === $c || ('' === $ret && '' === $c && null === $question->getDefault())) {
264-
shell_exec(sprintf('stty %s', $sttyMode));
270+
Terminal::restoreSttyMode($sttyMode);
265271
throw new MissingInputException('Aborted.');
266272
} elseif ("\177" === $c) { // Backspace Character
267273
if (0 === $numMatches && 0 !== $i) {
@@ -365,8 +371,7 @@ function ($match) use ($ret) {
365371
}
366372
}
367373

368-
// Reset stty so it behaves normally again
369-
shell_exec(sprintf('stty %s', $sttyMode));
374+
Terminal::restoreSttyMode($sttyMode);
370375

371376
return $fullChoice;
372377
}
@@ -418,7 +423,7 @@ private function getHiddenResponse(OutputInterface $output, $inputStream, bool $
418423
}
419424

420425
if (self::$stty && Terminal::hasSttyAvailable()) {
421-
$sttyMode = shell_exec('stty -g');
426+
$sttyMode = Terminal::backupSttyMode();
422427
shell_exec('stty -echo');
423428
} elseif ($this->isInteractiveInput($inputStream)) {
424429
throw new RuntimeException('Unable to hide the response.');
@@ -427,7 +432,7 @@ private function getHiddenResponse(OutputInterface $output, $inputStream, bool $
427432
$value = fgets($inputStream, 4096);
428433

429434
if (self::$stty && Terminal::hasSttyAvailable()) {
430-
shell_exec(sprintf('stty %s', $sttyMode));
435+
Terminal::restoreSttyMode($sttyMode);
431436
}
432437

433438
if (false === $value) {

src/Symfony/Component/Console/Terminal.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class Terminal
1616
private static $width;
1717
private static $height;
1818
private static $stty;
19+
private static $sttyMode;
1920

2021
/**
2122
* Gets the terminal width.
@@ -76,6 +77,25 @@ public static function hasSttyAvailable()
7677
return self::$stty = 0 === $exitcode;
7778
}
7879

80+
/**
81+
* @internal
82+
*/
83+
public static function backupSttyMode(string $sttyMode = null): string
84+
{
85+
return self::$sttyMode = $sttyMode ?? shell_exec('stty -g');
86+
}
87+
88+
/**
89+
* @internal
90+
*/
91+
public static function restoreSttymode(string $sttyMode = null): void
92+
{
93+
if (null !== $sttyMode = $sttyMode ?? self::$sttyMode) {
94+
shell_exec('stty '.$sttyMode);
95+
}
96+
self::$sttyMode = null;
97+
}
98+
7999 48E6
private static function initDimensions()
80100
{
81101
if ('\\' === \DIRECTORY_SEPARATOR) {

0 commit comments

Comments
 (0)
0