Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Console] Fix Console Ctrl-C terminal breaking issue#61740

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation

@mudassaralichouhan
Copy link

@mudassaralichouhanmudassaralichouhan commentedSep 12, 2025
edited by nicolas-grekas
Loading

QA
Branch?7.3
Bug fix?yes
New feature?no
Deprecations?no
IssuesFix#61732
LicenseMIT

The issue occurred when usingQuestionHelper withChoiceQuestion and a signal handler that callsexit(). The terminal would be left in raw mode (-icanon -echo) because thestty restoration only happened at the end of theautocomplete() method.

This fix:

  1. Registers signal handlers for common termination signals (SIGINT,SIGQUIT,SIGTERM, etc.)
  2. Uses atry-finally block to ensure terminal restoration even if exceptions occur or the process exits early
  3. Adds two private methods:
    • registerTerminalRestoreHandler() — sets up signal-safe terminal restoration
    • restoreTerminal() — restores the saved terminal mode viastty
  4. Ensures compatibility with Unix environments only (no effect on Windows)
  5. Maintains backward compatibility with existing code

Reproducer:https://github.com/johnstevenson/sigbug
Related issues:#44045,#48205,#57241

- Add signal handlers to restore terminal settings when Ctrl-C is pressed during choice selection- Wrap autocomplete method in try-finally block to ensure terminal restoration- Fixes issue where terminal would be left in raw mode when signal handlers call exit()-Resolvessymfony#61732The issue occurred when using QuestionHelper with ChoiceQuestion and a signal handlerthat calls exit(). The terminal would be left in raw mode (-icanon -echo) becausethe stty restoration only happened at the end of the autocomplete method.This fix:1. Registers signal handlers for common termination signals (SIGINT, SIGQUIT, SIGTERM, etc.)2. Uses try-finally to ensure terminal restoration even if exceptions occur3. Maintains backward compatibility with existing codeReproducer:https://github.com/johnstevenson/sigbugRelated issues:symfony#44045,symfony#48205,symfony#57241
@carsonbot
Copy link

Hey!

Thanks for your PR. You are targeting branch "7.4" but it seems your PR description refers to branch "7.3".
Could you update the PR description or change target branch? This helps core maintainers a lot.

Cheers!

Carsonbot

@carsonbotcarsonbot changed the titleFix Console Ctrl-C terminal breaking issue (#61732) Fix Console Ctrl-C terminal breaking issue (#61732)Sep 12, 2025
@nicolas-grekasnicolas-grekas changed the title Fix Console Ctrl-C terminal breaking issue (#61732) Fix Console Ctrl-C terminal breaking issueSep 13, 2025
@carsonbotcarsonbot changed the title Fix Console Ctrl-C terminal breaking issue[Console] Fix Console Ctrl-C terminal breaking issueSep 13, 2025
Comment on lines 379 to 380
// Always restore terminal settings, even if an exception occurs
$this->restoreTerminal($sttyMode);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This would at the very least need to restore previous signal handlers.. But it also needs to call the previous signal handlers when a signal triggers for full compatibility IMO. So this is definitely not a complete fix as it is.

@johnstevenson
Copy link
Contributor

Strange, but this doesn't fix anything when I use your code in the reproducer.

@johnstevenson
Copy link
Contributor

johnstevenson commentedSep 15, 2025
edited
Loading

Ah, you clearly haven't tested this. The reason it doesn't work is that the signal handlers are never set. You need to fix this so thatpcntl_signal($signal, $restoreHandler) is actually called.

The issue occurred when using QuestionHelper with ChoiceQuestion and a signal handler that calls exit().

The issue also occurs in a restarted process as well. While you have ensured that the terminal continues to work, you have unfortunately replaced any user signal handler with your own, which doesn't call exit, thus defeating the most common use of Ctrl-C. You've also wiped out the user signal handler for the remainder of the process after a choice question.

I've updated thereproducer so that the questions are called twice, which makes it more obvious where Ctrl-C has been called.

I think you need to do the following:

  • save the signal handler for each signal and run it after you have reset the terminal in your handler. For a callable, invoke it, for SIG_DFL exit with an appropriate exit code, and for SIG_IGN do nothing more.
  • restore these signal handlers afterwards (inrestoreTerminal).
  • for Ctrl-C signals, perhaps echo^C in the handler so it is clear to the user that the signal has been received.

@nicolas-grekas
Copy link
Member

On review, I wondered if this implementation, if made to work, won't collide with signal handlers as managed by the application?

@johnstevenson
Copy link
Contributor

On review, I wondered if this implementation, if made to work, won't collide with signal handlers as managed by the application?

Provided that existing signal handlers are saved before the choice question, invoked as I described above if signalled in the choice question, then restored afterwards, then there shouldn't be any collisions. Well that's the theory, anyway.

@mudassaralichouhan
Copy link
Author

mudassaralichouhan commentedSep 15, 2025
edited
Loading

You can verify the fix by running this command, which simulates a Ctrl-C during the interactive prompt and checks the terminal state before and after:

orig=$(stty -g); php sigbug handler& pid=$!; sleep 1;kill -INT$pid;wait$pid;echo"-- stty after --"; stty -a; stty$orig;echo"-- restored --"; stty -a

This test was performed on macOS with an M1 chip. Please let me know if you need assistance testing on other platforms or with the restart scenario.

@johnstevenson
Copy link
Contributor

Thanks for the fixes. However, registering lots of shutdown functions is not ideal or even necessary. I think you are making things a bit too complicated and could use something like this to set the SIGINT handler:

$signalHandler =null;if (\function_exists('pcntl_async_signals') &&\function_exists('pcntl_signal')) {pcntl_async_signals(true);$signalHandler =pcntl_signal_get_handler(\SIGINT);pcntl_signal(\SIGINT,function ($signo)use ($sttyMode,$signalHandler) {echo'^C', \PHP_EOL;shell_exec('stty'.$sttyMode);// Original handler will be a callable, SIG_DFL or SIG_IGNif (\is_callable($signalHandler)) {$signalHandler($signo);return;        }if ($signalHandler === \SIG_DFL) {exit(128 +$signo);        }    });}

Then call the following (either before throwing the exception and at the end of the function, or just once in a try, finally block);

// Restore terminal and original SIGINT handlershell_exec('stty'.$sttyMode);if ($signalHandler !==null) {pcntl_signal(\SIGINT,$signalHandler);}

@johnstevenson
Copy link
Contributor

You can verify the fix by running this command, which simulates a Ctrl-C during the interactive prompt and checks the terminal state before and after

This command does not work for me because it shows the same stty state with the broken code. In my terminal the signal stops the process, then restores the terminal so it can tell me it has done so and allow me to resume withfg #1.

@nicolas-grekas
Copy link
Member

Closing in favor of#61861, thanks for giving this a try!

@mudassaralichouhanmudassaralichouhan deleted the fix/console-ctrl-c-terminal-breaking branchOctober 2, 2025 07:23
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@chalasrchalasrAwaiting requested review from chalasrchalasr is a code owner

@SeldaekSeldaekAwaiting requested review from Seldaek

Assignees

No one assigned

Projects

None yet

Milestone

7.4

Development

Successfully merging this pull request may close these issues.

[Console] Ctrl-C can break the terminal when selecting input from a list

5 participants

@mudassaralichouhan@carsonbot@johnstevenson@nicolas-grekas@Seldaek

[8]ページ先頭

©2009-2025 Movatter.jp