summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Platform
diff options
context:
space:
mode:
authorTom Tanner <ttanner2@bloomberg.net>2013-10-03 16:07:25 (GMT)
committerTom Tanner <ttanner2@bloomberg.net>2013-10-03 16:07:25 (GMT)
commitd83777e9c6b676c0051d120bf3405e9117a031cf (patch)
tree88ba7c0c1a856ffcbfcd4cc5303a2274d02cf716 /src/engine/SCons/Platform
parent43f296c7c2a350de0c59a442e566c165420803e3 (diff)
downloadSCons-d83777e9c6b676c0051d120bf3405e9117a031cf.zip
SCons-d83777e9c6b676c0051d120bf3405e9117a031cf.tar.gz
SCons-d83777e9c6b676c0051d120bf3405e9117a031cf.tar.bz2
Stop leaking of filehandles to child processes by closing on fork.
Note: The close on fork bit you can set with ioctl isn't thread safe, and only linux allows you to set it on open
Diffstat (limited to 'src/engine/SCons/Platform')
-rw-r--r--src/engine/SCons/Platform/posix.py11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py
index ece48d7..3da1be7 100644
--- a/src/engine/SCons/Platform/posix.py
+++ b/src/engine/SCons/Platform/posix.py
@@ -47,6 +47,11 @@ exitvalmap = {
13 : 126,
}
+try:
+ MAXFD = os.sysconf("SC_OPEN_MAX")
+except:
+ MAXFD = 256
+
def escape(arg):
"escape shell special characters"
slash = '\\'
@@ -70,11 +75,12 @@ def exec_spawnvpe(l, env):
# returned by os.waitpid() or os.system().
return stat
-def exec_fork(l, env):
+def exec_fork(l, env):
pid = os.fork()
if not pid:
# Child process.
exitval = 127
+ os.closerange(3, MAXFD)
try:
os.execvpe(l[0], l, env)
except OSError, e:
@@ -161,6 +167,7 @@ def exec_piped_fork(l, env, stdout, stderr):
os.close( wFdOut )
if stdout != stderr:
os.close( wFdErr )
+ os.closerange(3, MAXFD)
exitval = 127
try:
os.execvpe(l[0], l, env)
@@ -205,7 +212,7 @@ def piped_fork_spawn(sh, escape, cmd, args, env, stdout, stderr):
def generate(env):
# If os.spawnvpe() exists, we use it to spawn commands. Otherwise
# if the env utility exists, we use os.system() to spawn commands,
- # finally we fall back on os.fork()/os.exec().
+ # finally we fall back on os.fork()/os.exec().
#
# os.spawnvpe() is prefered because it is the most efficient. But
# for Python versions without it, os.system() is prefered because it