Commit bf7eaf9e authored by Guido van Rossum's avatar Guido van Rossum

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.
parent a835d97c
...@@ -17,6 +17,7 @@ else: ...@@ -17,6 +17,7 @@ else:
has_stat = 0 has_stat = 0
has_textmode = (tempfile._text_openflags != tempfile._bin_openflags) 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 # 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) # number of files that can be opened at one time (see ulimit -n)
...@@ -323,39 +324,33 @@ class test__mkstemp_inner(TC): ...@@ -323,39 +324,33 @@ class test__mkstemp_inner(TC):
def test_noinherit(self): def test_noinherit(self):
"""_mkstemp_inner file handles are not inherited by child processes""" """_mkstemp_inner file handles are not inherited by child processes"""
# FIXME: Find a way to test this on Windows. if not has_spawnl:
if os.name != 'posix':
return # ugh, can't use TestSkipped. return # ugh, can't use TestSkipped.
if test_support.verbose:
v="v"
else:
v="q"
file = self.do_create() file = self.do_create()
fd = "%d" % file.fd
# We have to exec something, so that FD_CLOEXEC will take try:
# effect. The sanest thing to try is /bin/sh; we can easily me = __file__
# instruct it to attempt to write to the fd and report success except NameError:
# or failure. Unfortunately, sh syntax does not permit use of me = sys.argv[0]
# 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")
else: # We have to exec something, so that FD_CLOEXEC will take
try: # effect. The core of this test is therefore in
# Throw away stderr. # tf_inherit_check.py, which see.
nul = os.open('/dev/null', os.O_RDWR) tester = os.path.join(os.path.dirname(os.path.abspath(me)),
os.dup2(nul, 2) "tf_inherit_check.py")
os.execv('/bin/sh', ['sh', '-c', 'echo blat >&%d' % file.fd])
except: retval = os.spawnl(os.P_WAIT, sys.executable,
os._exit(0) 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): def test_textmode(self):
"""_mkstemp_inner can create files in text mode""" """_mkstemp_inner can create files in text mode"""
......
# 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)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment