Skip to content

Commit 1502441

Browse files
serhiy-storchakaclaude
authored andcommitted
gh-154345: Fix test_posix_pty_functions() killing the worker on Solaris (GH-154346)
Pushing the "ptem" STREAMS module makes a session leader without a controlling terminal acquire the slave as one, so closing the file descriptors sent SIGHUP to the session and killed the regrtest worker. Disown it after the pushes, as os.openpty() does. (cherry picked from commit f69f7fd) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 0942455 commit 1502441

1 file changed

Lines changed: 17 additions & 2 deletions

File tree

Lib/test/test_os.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4789,12 +4789,27 @@ def test_posix_pty_functions(self):
47894789
son_fd = os.open(son_path, os.O_RDWR|os.O_NOCTTY)
47904790
self.addCleanup(os.close, son_fd)
47914791
if sys.platform.startswith('sunos'):
4792-
# The slave is not a terminal until these STREAMS modules
4793-
# are pushed onto it.
47944792
import fcntl
47954793
I_PUSH = 0x5302
4794+
TIOCNOTTY = 0x7471
4795+
# Pushing "ptem" makes the slave a terminal, which a session
4796+
# leader without a controlling terminal then acquires as one
4797+
# despite O_NOCTTY. Note whether we already had one.
4798+
try:
4799+
os.close(os.open('/dev/tty', os.O_RDONLY|os.O_NOCTTY))
4800+
had_ctty = True
4801+
except OSError:
4802+
had_ctty = False
47964803
fcntl.ioctl(son_fd, I_PUSH, b'ptem\0')
47974804
fcntl.ioctl(son_fd, I_PUSH, b'ldterm\0')
4805+
if not had_ctty and os.getsid(0) == os.getpid():
4806+
# Disown it, otherwise closing the file descriptors sends
4807+
# SIGHUP to the session. TIOCNOTTY sends it too.
4808+
old_handler = signal.signal(signal.SIGHUP, signal.SIG_IGN)
4809+
try:
4810+
fcntl.ioctl(son_fd, TIOCNOTTY)
4811+
finally:
4812+
signal.signal(signal.SIGHUP, old_handler)
47984813
self.assertEqual(os.ptsname(mother_fd), os.ttyname(son_fd))
47994814

48004815
@unittest.skipUnless(hasattr(os, 'spawnl'), "need os.spawnl()")

0 commit comments

Comments
 (0)