summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2016-10-15 16:19:17 +0200
committerGiampaolo Rodola <g.rodola@gmail.com>2016-10-15 16:19:17 +0200
commite780cd448b0360cbf19657c242bc1ec7535114c3 (patch)
treed593f0f8d865bf3fbe48c6be9d86e33136be0661
parentef2ac7917e747acea53584dcb98fd9697d39f645 (diff)
downloadpsutil-e780cd448b0360cbf19657c242bc1ec7535114c3.tar.gz
improve reap_children() so that it closes all subprocess fds
-rw-r--r--psutil/__init__.py3
-rw-r--r--psutil/tests/__init__.py20
2 files changed, 18 insertions, 5 deletions
diff --git a/psutil/__init__.py b/psutil/__init__.py
index 2d5c974c..9c446b53 100644
--- a/psutil/__init__.py
+++ b/psutil/__init__.py
@@ -1277,7 +1277,8 @@ class Popen(Process):
self.stdout.close()
if self.stderr:
self.stderr.close()
- try: # Flushing a BufferedWriter may raise an error
+ try:
+ # Flushing a BufferedWriter may raise an error.
if self.stdin:
self.stdin.close()
finally:
diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py
index 7cf820cc..cf90a63c 100644
--- a/psutil/tests/__init__.py
+++ b/psutil/tests/__init__.py
@@ -264,6 +264,8 @@ def reap_children(recursive=False):
else:
children = []
+ # Terminate subprocess.Popen instances "cleanly" by closing their
+ # fds and wiat()ing for them in order to avoid zombies.
subprocs = _subprocesses_started.copy()
_subprocesses_started.clear()
for subp in subprocs:
@@ -272,11 +274,21 @@ def reap_children(recursive=False):
except OSError as err:
if err.errno != errno.ESRCH:
raise
+ if subp.stdout:
+ subp.stdout.close()
+ if subp.stderr:
+ subp.stderr.close()
try:
- subp.wait()
- except OSError as err:
- if err.errno != errno.ECHILD:
- raise
+ # Flushing a BufferedWriter may raise an error.
+ if subp.stdin:
+ subp.stdin.close()
+ finally:
+ # Wait for the process to terminate, to avoid zombies.
+ try:
+ subp.wait()
+ except OSError as err:
+ if err.errno != errno.ECHILD:
+ raise
if children:
for p in children: