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.
--- a/tests/test-stdio.py Thu Jul 16 23:49:04 2020 +0200
+++ b/tests/test-stdio.py Fri Jul 17 00:37:33 2020 +0200
@@ -16,6 +16,25 @@
from mercurial import pycompat
+if pycompat.ispy3:
+
+ def set_noninheritable(fd):
+ # On Python 3, file descriptors are non-inheritable by default.
+ pass
+
+
+else:
+ if pycompat.iswindows:
+ # unused
+ set_noninheritable = None
+ else:
+ import fcntl
+
+ def set_noninheritable(fd):
+ old = fcntl.fcntl(fd, fcntl.F_GETFD)
+ fcntl.fcntl(fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
+
+
TEST_BUFFERING_CHILD_SCRIPT = r'''
import os
@@ -64,9 +83,15 @@
pass
+# In the following, we set the FDs non-inheritable mainly to make it possible
+# for tests to close the receiving end of the pipe / PTYs.
+
+
@contextlib.contextmanager
def _devnull():
devnull = os.open(os.devnull, os.O_WRONLY)
+ # We don't have a receiving end, so it's not worth the effort on Python 2
+ # on Windows to make the FD non-inheritable.
with _closing([devnull]):
yield (None, devnull)
@@ -74,6 +99,10 @@
@contextlib.contextmanager
def _pipes():
rwpair = os.pipe()
+ # Pipes are already non-inheritable on Windows.
+ if not pycompat.iswindows:
+ set_noninheritable(rwpair[0])
+ set_noninheritable(rwpair[1])
with _closing(rwpair):
yield rwpair
@@ -86,6 +115,8 @@
import tty
rwpair = pty.openpty()
+ set_noninheritable(rwpair[0])
+ set_noninheritable(rwpair[1])
with _closing(rwpair):
tty.setraw(rwpair[0])
yield rwpair