Skip to content

Commit fd10c44

Browse files
[3.14] gh-154225: Fix os.openpty() acquiring a controlling terminal on Solaris (GH-154229) (GH-154256)
(cherry picked from commit a0caab9) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 91a5721 commit fd10c44

2 files changed

Lines changed: 21 additions & 0 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :func:`os.openpty` on Solaris and illumos: it no longer leaves the
2+
pseudo-terminal as the controlling terminal of the calling process.

Modules/posixmodule.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8960,11 +8960,30 @@ os_openpty_impl(PyObject *module)
89608960
goto posix_error;
89618961

89628962
#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
8963+
// Pushing "ptem" makes the slave a terminal, which a session leader
8964+
// without a controlling terminal then acquires as one despite O_NOCTTY.
8965+
// Note whether we already had one, so a new one can be disowned below.
8966+
int had_ctty = 0;
8967+
#ifdef TIOCNOTTY
8968+
int tty_fd = open("/dev/tty", O_RDONLY | O_NOCTTY);
8969+
if (tty_fd >= 0) {
8970+
had_ctty = 1;
8971+
close(tty_fd);
8972+
}
8973+
#endif
89638974
ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
89648975
ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
89658976
#ifndef __hpux
89668977
ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
89678978
#endif /* __hpux */
8979+
#ifdef TIOCNOTTY
8980+
if (!had_ctty && getsid(0) == getpid()) {
8981+
// Disown it; TIOCNOTTY sends SIGHUP to the session leader.
8982+
PyOS_sighandler_t sig_saved = PyOS_setsig(SIGHUP, SIG_IGN);
8983+
ioctl(slave_fd, TIOCNOTTY);
8984+
PyOS_setsig(SIGHUP, sig_saved);
8985+
}
8986+
#endif
89688987
#endif /* HAVE_CYGWIN */
89698988
#endif /* HAVE_OPENPTY */
89708989

0 commit comments

Comments
 (0)