summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tanner <ttanner2@bloomberg.net>2013-10-03 17:07:25 +0100
committerTom Tanner <ttanner2@bloomberg.net>2013-10-03 17:07:25 +0100
commitf6466f00a8b0f06236073335ccfdc8ca16add960 (patch)
tree643b4e39bf70296a957f4ed7fa8b41c02c833500
parenta49975c0e4a81cf6089250a4e32484afd43f6245 (diff)
downloadscons-f6466f00a8b0f06236073335ccfdc8ca16add960.tar.gz
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
-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 ece48d7d..3da1be72 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