diff options
| author | John Estabrook <jestabro@vyos.io> | 2026-08-13 09:24:25 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-13 09:24:25 -0500 |
| commit | 738eb3461ff70234e05f08bbbe1568d14ae4132e (patch) | |
| tree | e87fc1d2433a15331eec04e36a7502b7ebdefb47 /python | |
| parent | ba8924dd23477c4fb9635858b23e9945f9b4ddbd (diff) | |
| parent | 6396d9aa43063569dfc9be2daac27f89a643252f (diff) | |
| download | vyos-1x-738eb3461ff70234e05f08bbbe1568d14ae4132e.tar.gz vyos-1x-738eb3461ff70234e05f08bbbe1568d14ae4132e.zip | |
Merge pull request #5390 from ruben-herold/T9185-commit-confirm-cpu-spin
utils: T9185: fix ask_yes_no() busy-looping forever on non-tty stdin
Diffstat (limited to 'python')
| -rw-r--r-- | python/vyos/utils/io.py | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/python/vyos/utils/io.py b/python/vyos/utils/io.py index 77e30cbb0..58ceb3476 100644 --- a/python/vyos/utils/io.py +++ b/python/vyos/utils/io.py @@ -55,8 +55,25 @@ def ask_input(question, default='', numeric_only=False, valid_responses=[], return response def ask_yes_no(question, default=False) -> bool: - """Ask a yes/no question via input() and return their answer.""" - from sys import stdout + """Ask a yes/no question via input() and return their answer. + + Raises EOFError immediately if stdin is not a TTY (e.g. non-interactive + scripts), instead of ever calling input(). A silent default here has + caused real incidents (T9185): a caller that forgets to guard an + interactive-only prompt gets no error and no visible hang, just a + process quietly pegging a core. Callers that are meant to run + non-interactively must check for that explicitly (see the no_prompt + parameter used across config_mgmt.py/backend.py) rather than rely on + this function to fall back to a default. + """ + from sys import stdin, stdout + + if not stdin.isatty(): + raise EOFError( + f'Cannot prompt "{question}" ([Y/n] default={default}): ' + 'stdin is not a TTY. Pass an explicit non-interactive option ' + '(e.g. no_prompt/-y) instead of relying on ask_yes_no().' + ) default_msg = "[Y/n]" if default else "[y/N]" while True: try: |
