goto posix_error;
#if defined(HAVE_STROPTS_H) && !defined(HAVE_DEV_PTC)
+ // Pushing "ptem" makes the slave a terminal, which a session leader
+ // without a controlling terminal then acquires as one despite O_NOCTTY.
+ // Note whether we already had one, so a new one can be disowned below.
+ int had_ctty = 0;
+#ifdef TIOCNOTTY
+ int tty_fd = open("/dev/tty", O_RDONLY | O_NOCTTY);
+ if (tty_fd >= 0) {
+ had_ctty = 1;
+ close(tty_fd);
+ }
+#endif
ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
#ifndef __hpux
ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
#endif /* __hpux */
+#ifdef TIOCNOTTY
+ if (!had_ctty && getsid(0) == getpid()) {
+ // Disown it; TIOCNOTTY sends SIGHUP to the session leader.
+ PyOS_sighandler_t sig_saved = PyOS_setsig(SIGHUP, SIG_IGN);
+ ioctl(slave_fd, TIOCNOTTY);
+ PyOS_setsig(SIGHUP, sig_saved);
+ }
+#endif
#endif /* defined(HAVE_STROPTS_H) && !defined(HAVE_DEV_PTC) */
#endif /* HAVE_OPENPTY */