summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2002-08-17 11:41:01 (GMT)
committerGuido van Rossum <guido@python.org>2002-08-17 11:41:01 (GMT)
commit787410680b9866d56a1ec1915ebbf41ab5cac7a0 (patch)
treef10e42f67d9365ed7912d6c2334be48bd147c639
parentb898d9fc9a434eb9ae9d3d10d0f1d379492cd6f6 (diff)
downloadcpython-787410680b9866d56a1ec1915ebbf41ab5cac7a0.zip
cpython-787410680b9866d56a1ec1915ebbf41ab5cac7a0.tar.gz
cpython-787410680b9866d56a1ec1915ebbf41ab5cac7a0.tar.bz2
Patch by Zack W to make test_noinherit() more robust: spawn a Python
subprocess that does the right checks. This now works on Windows as well.
-rw-r--r--Lib/test/test_tempfile.py51
-rw-r--r--Lib/test/tf_inherit_check.py25
2 files changed, 48 insertions, 28 deletions
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index 0e1c891..575986f 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -17,6 +17,7 @@ else:
has_stat = 0
has_textmode = (tempfile._text_openflags != tempfile._bin_openflags)
+has_spawnl = hasattr(os, 'spawnl')
# TEST_FILES may need to be tweaked for systems depending on the maximum
# number of files that can be opened at one time (see ulimit -n)
@@ -323,39 +324,33 @@ class test__mkstemp_inner(TC):
def test_noinherit(self):
"""_mkstemp_inner file handles are not inherited by child processes"""
- # FIXME: Find a way to test this on Windows.
- if os.name != 'posix':
+ if not has_spawnl:
return # ugh, can't use TestSkipped.
+ if test_support.verbose:
+ v="v"
+ else:
+ v="q"
+
file = self.do_create()
+ fd = "%d" % file.fd
- # We have to exec something, so that FD_CLOEXEC will take
- # effect. The sanest thing to try is /bin/sh; we can easily
- # instruct it to attempt to write to the fd and report success
- # or failure. Unfortunately, sh syntax does not permit use of
- # fds numerically larger than 9; abandon this test if so.
- if file.fd > 9:
- raise test_support.TestSkipped, 'cannot test with fd %d' % file.fd
-
- pid = os.fork()
- if pid:
- status = os.wait()[1]
- self.failUnless(os.WIFEXITED(status),
- "child process did not exit (status %d)" % status)
-
- # We want the child to have exited _un_successfully, indicating
- # failure to write to the closed fd.
- self.failUnless(os.WEXITSTATUS(status) != 0,
- "child process exited successfully")
+ try:
+ me = __file__
+ except NameError:
+ me = sys.argv[0]
- else:
- try:
- # Throw away stderr.
- nul = os.open('/dev/null', os.O_RDWR)
- os.dup2(nul, 2)
- os.execv('/bin/sh', ['sh', '-c', 'echo blat >&%d' % file.fd])
- except:
- os._exit(0)
+ # We have to exec something, so that FD_CLOEXEC will take
+ # effect. The core of this test is therefore in
+ # tf_inherit_check.py, which see.
+ tester = os.path.join(os.path.dirname(os.path.abspath(me)),
+ "tf_inherit_check.py")
+
+ retval = os.spawnl(os.P_WAIT, sys.executable,
+ sys.executable, tester, v, fd)
+ self.failIf(retval < 0,
+ "child process caught fatal signal %d" % -retval)
+ self.failIf(retval > 0, "child process reports failure")
def test_textmode(self):
"""_mkstemp_inner can create files in text mode"""
diff --git a/Lib/test/tf_inherit_check.py b/Lib/test/tf_inherit_check.py
new file mode 100644
index 0000000..a8b80d2
--- /dev/null
+++ b/Lib/test/tf_inherit_check.py
@@ -0,0 +1,25 @@
+# Helper script for test_tempfile.py. argv[2] is the number of a file
+# descriptor which should _not_ be open. Check this by attempting to
+# write to it -- if we succeed, something is wrong.
+
+import sys
+import os
+
+verbose = (sys.argv[1] == 'v')
+try:
+ fd = int(sys.argv[2])
+
+ try:
+ os.write(fd, "blat")
+ except os.error:
+ # Success -- could not write to fd.
+ sys.exit(0)
+ else:
+ if verbose:
+ sys.stderr.write("fd %d is open in child" % fd)
+ sys.exit(1)
+
+except StandardError:
+ if verbose:
+ raise
+ sys.exit(1)