Skip to content

Commit 03481c7

Browse files
committed
fix: readline doesn't degrade gracefully when tcsetattr() fails.
Signed-off-by: yihong0618 <[email protected]>
1 parent d6dd64a commit 03481c7

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix: Basic REPL hangs when ioctls can't be written to TTY.

Modules/readline.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include <signal.h> // SIGWINCH
1818
#include <stdlib.h> // free()
1919
#include <string.h> // strdup()
20+
#include <termios.h> // termios, tcgetattr(), tcsetattr()
21+
#include <unistd.h> // isatty(), STDIN_FILENO
2022
#ifdef HAVE_SYS_SELECT_H
2123
# include <sys/select.h> // select()
2224
#endif
@@ -1645,6 +1647,20 @@ PyInit_readline(void)
16451647
if (mod_state == NULL){
16461648
goto error;
16471649
}
1650+
1651+
// gh-139027: If tcsetattr fails do not initialize readline and err it
1652+
if (isatty(STDIN_FILENO)) {
1653+
struct termios original_tty;
1654+
if (tcgetattr(STDIN_FILENO, &original_tty) == 0) {
1655+
struct termios test_tty = original_tty;
1656+
if (tcsetattr(STDIN_FILENO, TCSANOW, &test_tty) != 0) {
1657+
PyErr_SetString(PyExc_OSError,
1658+
"termios failure (Operation not permitted)");
1659+
goto error;
1660+
}
1661+
}
1662+
}
1663+
16481664
PyOS_ReadlineFunctionPointer = call_readline;
16491665
if (setup_readline(mod_state) < 0) {
16501666
PyErr_NoMemory();

0 commit comments

Comments
 (0)