comparison tests/test-stdio.py @ 45147:c2c862b9b544

tests: make pipes / PTYs non-inheritable in test-stdio.py A following patch requires that to test closing the receiving end of the pipe / PTYs. Even for existing tests, it might be safer to make the lifetime of the pipes / PTYs as short as possible.
author Manuel Jacob <me@manueljacob.de>
date Fri, 17 Jul 2020 00:37:33 +0200
parents eb26a9cf7821
children a37f290a7124
comparison
equal deleted inserted replaced
45146:a0791bfd9cfa 45147:c2c862b9b544
12 import sys 12 import sys
13 import tempfile 13 import tempfile
14 import unittest 14 import unittest
15 15
16 from mercurial import pycompat 16 from mercurial import pycompat
17
18
19 if pycompat.ispy3:
20
21 def set_noninheritable(fd):
22 # On Python 3, file descriptors are non-inheritable by default.
23 pass
24
25
26 else:
27 if pycompat.iswindows:
28 # unused
29 set_noninheritable = None
30 else:
31 import fcntl
32
33 def set_noninheritable(fd):
34 old = fcntl.fcntl(fd, fcntl.F_GETFD)
35 fcntl.fcntl(fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
17 36
18 37
19 TEST_BUFFERING_CHILD_SCRIPT = r''' 38 TEST_BUFFERING_CHILD_SCRIPT = r'''
20 import os 39 import os
21 40
62 os.close(fd) 81 os.close(fd)
63 except EnvironmentError: 82 except EnvironmentError:
64 pass 83 pass
65 84
66 85
86 # In the following, we set the FDs non-inheritable mainly to make it possible
87 # for tests to close the receiving end of the pipe / PTYs.
88
89
67 @contextlib.contextmanager 90 @contextlib.contextmanager
68 def _devnull(): 91 def _devnull():
69 devnull = os.open(os.devnull, os.O_WRONLY) 92 devnull = os.open(os.devnull, os.O_WRONLY)
93 # We don't have a receiving end, so it's not worth the effort on Python 2
94 # on Windows to make the FD non-inheritable.
70 with _closing([devnull]): 95 with _closing([devnull]):
71 yield (None, devnull) 96 yield (None, devnull)
72 97
73 98
74 @contextlib.contextmanager 99 @contextlib.contextmanager
75 def _pipes(): 100 def _pipes():
76 rwpair = os.pipe() 101 rwpair = os.pipe()
102 # Pipes are already non-inheritable on Windows.
103 if not pycompat.iswindows:
104 set_noninheritable(rwpair[0])
105 set_noninheritable(rwpair[1])
77 with _closing(rwpair): 106 with _closing(rwpair):
78 yield rwpair 107 yield rwpair
79 108
80 109
81 @contextlib.contextmanager 110 @contextlib.contextmanager
84 raise unittest.SkipTest("PTYs are not supported on Windows") 113 raise unittest.SkipTest("PTYs are not supported on Windows")
85 import pty 114 import pty
86 import tty 115 import tty
87 116
88 rwpair = pty.openpty() 117 rwpair = pty.openpty()
118 set_noninheritable(rwpair[0])
119 set_noninheritable(rwpair[1])
89 with _closing(rwpair): 120 with _closing(rwpair):
90 tty.setraw(rwpair[0]) 121 tty.setraw(rwpair[0])
91 yield rwpair 122 yield rwpair
92 123
93 124