Closed
Description
Symfony version(s) affected: 4.1
Description
If the user sends a SIGINT
(CTRL+C
) during the autocomplete phase of question ask, the stty will not be restored to its original state. This means that the console will not echo as the user types until they type stty echo
(which they cannot see).
How to reproduce
This applies to linux and windows but I only created a test for windows.
This is a disaster of a test case because I needed to mock out shell_exec
& stty
somehow... 🤷♂️
//as part of QuestionHelperTest
/**
* @runInSeparateProcess
*/
public function testAskWithAutocompleteRestoresSttyOnSigInt()
{
if(DIRECTORY_SEPARATOR === '/') {
$this->markTestSkipped('Must run in windows');
}
$tempDir = getcwd().'/__temp';
@mkdir($tempDir);
chdir($tempDir);
//this writes the stty arguments to the test file for inspection and returns a mode=restored for stty -g
$sttyMock = "@echo off\r\necho \"%0 %*\" > stty.out\r\necho|set /p dummy=restored";
file_put_contents('stty.bat', $sttyMock);
register_shutdown_function(function() use ($tempDir) {
$this->assertContains('restored', file_get_contents($tempDir . '/stty.out'));
});
$dialog = new QuestionHelper();
$question = new Question('How are you');
$question->setAutocompleterValues(array('Good', 'Bad'));
//force an exit when ! is detected in the input stream
$output = new class extends Output {
protected function doWrite($message, $newline)
{
if($message === '!') {
exit(1); //simulate a CTRL-C
}
}
};
$dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream('ABC!123')), $output, $question);
}
1) Symfony\Component\Console\Tests\Helper\QuestionHelperTest::testAskWithAutocompleteRestoresSttyOnSigInt
PHPUnit\Framework\Exception: PHP Fatal error: Uncaught Failed asserting that '"stty -icanon -echo" \r\n
' contains "restored".
Possible Solution
register_shutdown_function
can be used to add a handler that will restore the stty mode if it is not restored successfully. I looked into pcntl_signal
but it does not allow multiple handlers.
SIGINT seems to cause shutdown functions to not be called?