summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Platform/posix.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/SCons/Platform/posix.py')
-rw-r--r--src/engine/SCons/Platform/posix.py121
1 files changed, 116 insertions, 5 deletions
diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py
index 777b928..fd78de4 100644
--- a/src/engine/SCons/Platform/posix.py
+++ b/src/engine/SCons/Platform/posix.py
@@ -32,11 +32,13 @@ selection method.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import SCons.Util
-import string
import os
-import sys
import os.path
+import popen2
+import string
+import sys
+
+import SCons.Util
def escape(arg):
"escape shell special characters"
@@ -49,7 +51,7 @@ def escape(arg):
return '"' + arg + '"'
-def env_spawn(sh, escape, cmd, args, env):
+def _get_env_command(sh, escape, cmd, args, env):
if env:
s = 'env -i '
for key in env.keys():
@@ -58,7 +60,10 @@ def env_spawn(sh, escape, cmd, args, env):
s = s + escape(string.join(args))
else:
s = string.join(args)
+ return s
+def env_spawn(sh, escape, cmd, args, env):
+ s = _get_env_command( sh, escape, cmd, args, env)
stat = os.system(s)
if stat & 0xff:
return stat | 0x80
@@ -82,7 +87,110 @@ def fork_spawn(sh, escape, cmd, args, env):
if stat & 0xff:
return stat | 0x80
return stat >> 8
-
+
+def piped_env_spawn(sh, escape, cmd, args, env, stdout, stderr):
+ # spawn using Popen3 combined with the env command
+ # the command name and the command's stdout is written to stdout
+ # the command's stderr is written to stderr
+ s = _get_env_command( sh, escape, cmd, args, env)
+ # write the command line out
+ if stdout != None:
+ stdout.write(string.join(args) + '\n')
+ proc = popen2.Popen3(s, 1)
+ # process stdout
+ if stdout != None:
+ #for line in proc.fromchild.xreadlines():
+ # stdout.write(line)
+ while 1:
+ line = proc.fromchild.readline()
+ if not line:
+ break
+ stdout.write(line)
+ # process stderr
+ if stderr != None:
+ #for line in proc.childerr.xreadlines():
+ # stderr.write(line)
+ while 1:
+ line = proc.childerr.readline()
+ if not line:
+ break
+ stderr.write(line)
+ stat = proc.wait()
+ if stat & 0xff:
+ return stat | 0x80
+ return stat >> 8
+
+def piped_fork_spawn(sh, escape, cmd, args, env, stdout, stderr):
+ # spawn using fork / exec and providing a pipe for the command's
+ # stdout / stderr stream
+ if stdout != stderr:
+ (rFdOut, wFdOut) = os.pipe()
+ (rFdErr, wFdErr) = os.pipe()
+ else:
+ (rFdOut, wFdOut) = os.pipe()
+ rFdErr = rFdOut
+ wFdErr = wFdOut
+ # write the command line out
+ if stdout != None:
+ stdout.write(string.join(args) + '\n')
+ # do the fork
+ pid = os.fork()
+ if not pid:
+ # Child process
+ os.close( rFdOut )
+ if rFdOut != rFdErr:
+ os.close( rFdErr )
+ os.dup2( wFdOut, 1 ) # is there some symbolic way to do that ?
+ os.dup2( wFdErr, 2 )
+ os.close( wFdOut )
+ if stdout != stderr:
+ os.close( wFdErr )
+ exitval = 127
+ args = [sh, '-c', string.join(args)]
+ try:
+ os.execvpe(sh, args, env)
+ except OSError, e:
+ exitval = exitvalmap[e[0]]
+ stderr.write("scons: %s: %s\n" % (cmd, e[1]))
+ os._exit(exitval)
+ else:
+ # Parent process
+ pid, stat = os.waitpid(pid, 0)
+ os.close( wFdOut )
+ if stdout != stderr:
+ os.close( wFdErr )
+ childOut = os.fdopen( rFdOut )
+ if stdout != stderr:
+ childErr = os.fdopen( rFdErr )
+ else:
+ childErr = childOut
+ # process stdout
+ if stdout != None:
+ #for line in childOut.xreadlines():
+ # stdout.write(line)
+ while 1:
+ line = childOut.readline()
+ if not line:
+ break
+ stdout.write(line)
+ # process stderr
+ if stderr != None:
+ #for line in childErr.xreadlines():
+ # stderr.write(line)
+ while 1:
+ line = childErr.readline()
+ if not line:
+ break
+ stdout.write(line)
+ os.close( rFdOut )
+ if stdout != stderr:
+ os.close( rFdErr )
+ if stat & 0xff:
+ return stat | 0x80
+ return stat >> 8
+
+
+
def generate(env):
# If the env command exists, then we can use os.system()
@@ -91,8 +199,10 @@ def generate(env):
# threads (i.e. -j) and is more efficient than forking Python.
if env.Detect('env'):
spawn = env_spawn
+ pspawn = piped_env_spawn
else:
spawn = fork_spawn
+ pspawn = piped_fork_spawn
if not env.has_key('ENV'):
env['ENV'] = {}
@@ -109,6 +219,7 @@ def generate(env):
env['SHLIBSUFFIX'] = '.so'
env['LIBPREFIXES'] = '$LIBPREFIX'
env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ]
+ env['PSPAWN'] = pspawn
env['SPAWN'] = spawn
env['SHELL'] = 'sh'
env['ESCAPE'] = escape