summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGregory P. Smith <greg@mad-scientist.com>2010-12-14 15:02:53 (GMT)
committerGregory P. Smith <greg@mad-scientist.com>2010-12-14 15:02:53 (GMT)
commit312efbc1158a15cb877d8bb078c19f95b23596e6 (patch)
tree199100b59037b96fa0b74b74c378f5edac8bb895
parentdacb8043ff1fb6fa33b5457f0405a1ca867ba2d3 (diff)
downloadcpython-312efbc1158a15cb877d8bb078c19f95b23596e6.zip
cpython-312efbc1158a15cb877d8bb078c19f95b23596e6.tar.gz
cpython-312efbc1158a15cb877d8bb078c19f95b23596e6.tar.bz2
Merged revisions 87233 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r87233 | gregory.p.smith | 2010-12-14 06:38:00 -0800 (Tue, 14 Dec 2010) | 4 lines Issue #1731717: Fixed the problem where subprocess.wait() could cause an OSError exception when The OS had been told to ignore SIGCLD in our process or otherwise not wait for exiting child processes. ........
-rw-r--r--Lib/subprocess.py16
-rw-r--r--Lib/test/subprocessdata/sigchild_ignore.py6
-rw-r--r--Lib/test/test_subprocess.py10
-rw-r--r--Misc/NEWS4
4 files changed, 34 insertions, 2 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 24bf321..4c235d9 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -1194,7 +1194,11 @@ class Popen(object):
os.close(errpipe_read)
if data != "":
- _eintr_retry_call(os.waitpid, self.pid, 0)
+ try:
+ _eintr_retry_call(os.waitpid, self.pid, 0)
+ except OSError as e:
+ if e.errno != errno.ECHILD:
+ raise
child_exception = pickle.loads(data)
for fd in (p2cwrite, c2pread, errread):
if fd is not None:
@@ -1240,7 +1244,15 @@ class Popen(object):
"""Wait for child process to terminate. Returns returncode
attribute."""
if self.returncode is None:
- pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
+ try:
+ pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
+ except OSError as e:
+ if e.errno != errno.ECHILD:
+ raise
+ # This happens if SIGCLD is set to be ignored or waiting
+ # for child processes has otherwise been disabled for our
+ # process. This child is dead, we can't get the status.
+ sts = 0
self._handle_exitstatus(sts)
return self.returncode
diff --git a/Lib/test/subprocessdata/sigchild_ignore.py b/Lib/test/subprocessdata/sigchild_ignore.py
new file mode 100644
index 0000000..1d03303
--- /dev/null
+++ b/Lib/test/subprocessdata/sigchild_ignore.py
@@ -0,0 +1,6 @@
+import signal, subprocess, sys
+# On Linux this causes os.waitpid to fail with OSError as the OS has already
+# reaped our child process. The wait() passing the OSError on to the caller
+# and causing us to exit with an error is what we are testing against.
+signal.signal(signal.SIGCLD, signal.SIG_IGN)
+subprocess.Popen([sys.executable, '-c', 'print("albatross")']).wait()
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 37c4e0f..26adf22 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -778,6 +778,16 @@ class POSIXProcessTestCase(BaseTestCase):
self.assertStderrEqual(stderr, '')
self.assertEqual(p.wait(), -signal.SIGTERM)
+ def test_wait_when_sigchild_ignored(self):
+ # NOTE: sigchild_ignore.py may not be an effective test on all OSes.
+ sigchild_ignore = test_support.findfile("sigchild_ignore.py",
+ subdir="subprocessdata")
+ p = subprocess.Popen([sys.executable, sigchild_ignore],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ self.assertEqual(0, p.returncode, "sigchild_ignore.py exited"
+ " non-zero with this error:\n%s" % stderr)
+
@unittest.skipUnless(mswindows, "Windows specific tests")
class Win32ProcessTestCase(BaseTestCase):
diff --git a/Misc/NEWS b/Misc/NEWS
index 2d12879..b49539b 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -34,6 +34,10 @@ Library
- Issue #10464: netrc now correctly handles lines with embedded '#' characters.
+- Issue #1731717: Fixed the problem where subprocess.wait() could cause an
+ OSError exception when The OS had been told to ignore SIGCLD in our process
+ or otherwise not wait for exiting child processes.
+
Extension Modules
-----------------