From 03481c73d119e8c507f06b3aa1097a979501cea5 Mon Sep 17 00:00:00 2001 From: yihong0618 Date: Sun, 12 Oct 2025 16:27:26 +0800 Subject: [PATCH] fix: readline doesn't degrade gracefully when tcsetattr() fails. Signed-off-by: yihong0618 --- ...025-10-12-16-27-01.gh-issue-139027.Rntwlp.rst | 1 + Modules/readline.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 Misc/NEWS.d/next/macOS/2025-10-12-16-27-01.gh-issue-139027.Rntwlp.rst diff --git a/Misc/NEWS.d/next/macOS/2025-10-12-16-27-01.gh-issue-139027.Rntwlp.rst b/Misc/NEWS.d/next/macOS/2025-10-12-16-27-01.gh-issue-139027.Rntwlp.rst new file mode 100644 index 00000000000000..d0fc33f9f5b332 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2025-10-12-16-27-01.gh-issue-139027.Rntwlp.rst @@ -0,0 +1 @@ +Fix: Basic REPL hangs when ioctls can't be written to TTY. diff --git a/Modules/readline.c b/Modules/readline.c index 630a6879990949..c83042ed92aeaf 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -17,6 +17,8 @@ #include // SIGWINCH #include // free() #include // strdup() +#include // termios, tcgetattr(), tcsetattr() +#include // isatty(), STDIN_FILENO #ifdef HAVE_SYS_SELECT_H # include // select() #endif @@ -1645,6 +1647,20 @@ PyInit_readline(void) if (mod_state == NULL){ goto error; } + + // gh-139027: If tcsetattr fails do not initialize readline and err it + if (isatty(STDIN_FILENO)) { + struct termios original_tty; + if (tcgetattr(STDIN_FILENO, &original_tty) == 0) { + struct termios test_tty = original_tty; + if (tcsetattr(STDIN_FILENO, TCSANOW, &test_tty) != 0) { + PyErr_SetString(PyExc_OSError, + "termios failure (Operation not permitted)"); + goto error; + } + } + } + PyOS_ReadlineFunctionPointer = call_readline; if (setup_readline(mod_state) < 0) { PyErr_NoMemory();