diff options
Diffstat (limited to 'src/engine/SCons/Platform/posix.py')
-rw-r--r-- | src/engine/SCons/Platform/posix.py | 121 |
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 |