Index: scons-2.0.1/engine/SCons/Platform/posix.py |
=================================================================== |
--- scons-2.0.1/engine/SCons/Platform/posix.py (revision 0) |
+++ scons-2.0.1/engine/SCons/Platform/posix.py (revision 0) |
@@ -0,0 +1,263 @@ |
+"""SCons.Platform.posix |
+ |
+Platform-specific initialization for POSIX (Linux, UNIX, etc.) systems. |
+ |
+There normally shouldn't be any need to import this module directly. It |
+will usually be imported through the generic SCons.Platform.Platform() |
+selection method. |
+""" |
+ |
+# |
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation |
+# |
+# Permission is hereby granted, free of charge, to any person obtaining |
+# a copy of this software and associated documentation files (the |
+# "Software"), to deal in the Software without restriction, including |
+# without limitation the rights to use, copy, modify, merge, publish, |
+# distribute, sublicense, and/or sell copies of the Software, and to |
+# permit persons to whom the Software is furnished to do so, subject to |
+# the following conditions: |
+# |
+# The above copyright notice and this permission notice shall be included |
+# in all copies or substantial portions of the Software. |
+# |
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY |
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE |
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
+# |
+ |
+__revision__ = "src/engine/SCons/Platform/posix.py 5134 2010/08/16 23:02:40 bdeegan" |
+ |
+import errno |
+import os |
+import os.path |
+import subprocess |
+import sys |
+import select |
+ |
+import SCons.Util |
+from SCons.Platform import TempFileMunge |
+ |
+exitvalmap = { |
+ 2 : 127, |
+ 13 : 126, |
+} |
+ |
+def escape(arg): |
+ "escape shell special characters" |
+ slash = '\\' |
+ special = '"$()' |
+ |
+ arg = arg.replace(slash, slash+slash) |
+ for c in special: |
+ arg = arg.replace(c, slash+c) |
+ |
+ return '"' + arg + '"' |
+ |
+def exec_system(l, env): |
+ stat = os.system(' '.join(l)) |
+ if stat & 0xff: |
+ return stat | 0x80 |
+ return stat >> 8 |
+ |
+def exec_spawnvpe(l, env): |
+ stat = os.spawnvpe(os.P_WAIT, l[0], l, env) |
+ # os.spawnvpe() returns the actual exit code, not the encoding |
+ # returned by os.waitpid() or os.system(). |
+ return stat |
+ |
+def exec_fork(l, env): |
+ pid = os.fork() |
+ if not pid: |
+ # Child process. |
+ exitval = 127 |
+ try: |
+ os.execvpe(l[0], l, env) |
+ except OSError, e: |
+ exitval = exitvalmap.get(e[0], e[0]) |
+ sys.stderr.write("scons: %s: %s\n" % (l[0], e[1])) |
+ os._exit(exitval) |
+ else: |
+ # Parent process. |
+ pid, stat = os.waitpid(pid, 0) |
+ if stat & 0xff: |
+ return stat | 0x80 |
+ return stat >> 8 |
+ |
+def _get_env_command(sh, escape, cmd, args, env): |
+ s = ' '.join(args) |
+ if env: |
+ l = ['env', '-'] + \ |
+ [escape(t[0])+'='+escape(t[1]) for t in env.items()] + \ |
+ [sh, '-c', escape(s)] |
+ s = ' '.join(l) |
+ return s |
+ |
+def env_spawn(sh, escape, cmd, args, env): |
+ return exec_system([_get_env_command( sh, escape, cmd, args, env)], env) |
+ |
+def spawnvpe_spawn(sh, escape, cmd, args, env): |
+ return exec_spawnvpe([sh, '-c', ' '.join(args)], env) |
+ |
+def fork_spawn(sh, escape, cmd, args, env): |
+ return exec_fork([sh, '-c', ' '.join(args)], env) |
+ |
+def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr): |
+ stdout_eof = stderr_eof = 0 |
+ while not (stdout_eof and stderr_eof): |
+ try: |
+ (i,o,e) = select.select([cmd_stdout, cmd_stderr], [], []) |
+ if cmd_stdout in i: |
+ str = cmd_stdout.read() |
+ if len(str) == 0: |
+ stdout_eof = 1 |
+ elif stdout is not None: |
+ stdout.write(str) |
+ if cmd_stderr in i: |
+ str = cmd_stderr.read() |
+ if len(str) == 0: |
+ #sys.__stderr__.write( "stderr_eof=1\n" ) |
+ stderr_eof = 1 |
+ else: |
+ #sys.__stderr__.write( "str(stderr) = %s\n" % str ) |
+ stderr.write(str) |
+ except select.error, (_errno, _strerror): |
+ if _errno != errno.EINTR: |
+ raise |
+ |
+def exec_popen3(l, env, stdout, stderr): |
+ proc = subprocess.Popen(' '.join(l), |
+ stdout=stdout, |
+ stderr=stderr, |
+ shell=True) |
+ stat = proc.wait() |
+ if stat & 0xff: |
+ return stat | 0x80 |
+ return stat >> 8 |
+ |
+def exec_piped_fork(l, 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 |
+ # 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 |
+ try: |
+ os.execvpe(l[0], l, env) |
+ except OSError, e: |
+ exitval = exitvalmap.get(e[0], e[0]) |
+ stderr.write("scons: %s: %s\n" % (l[0], 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_cmd_output(childOut, childErr, stdout, stderr) |
+ os.close( rFdOut ) |
+ if stdout != stderr: |
+ os.close( rFdErr ) |
+ 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 |
+ return exec_popen3([_get_env_command(sh, escape, cmd, args, env)], |
+ env, stdout, stderr) |
+ |
+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 |
+ return exec_piped_fork([sh, '-c', ' '.join(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(). |
+ # |
+ # os.spawnvpe() is prefered because it is the most efficient. But |
+ # for Python versions without it, os.system() is prefered because it |
+ # is claimed that it works better with threads (i.e. -j) and is more |
+ # efficient than forking Python. |
+ # |
+ # NB: Other people on the scons-users mailing list have claimed that |
+ # os.fork()/os.exec() works better than os.system(). There may just |
+ # not be a default that works best for all users. |
+ |
+ if 'spawnvpe' in os.__dict__: |
+ spawn = spawnvpe_spawn |
+ elif env.Detect('env'): |
+ spawn = env_spawn |
+ else: |
+ spawn = fork_spawn |
+ |
+ if env.Detect('env'): |
+ pspawn = piped_env_spawn |
+ else: |
+ pspawn = piped_fork_spawn |
+ |
+ if 'ENV' not in env: |
+ env['ENV'] = {} |
+ env['ENV']['PATH'] = '/usr/local/bin:/opt/bin:/bin:/usr/bin' |
+ env['OBJPREFIX'] = '' |
+ env['OBJSUFFIX'] = '.o' |
+ env['SHOBJPREFIX'] = '$OBJPREFIX' |
+ env['SHOBJSUFFIX'] = '$OBJSUFFIX' |
+ env['PROGPREFIX'] = '' |
+ env['PROGSUFFIX'] = '' |
+ env['LIBPREFIX'] = 'lib' |
+ env['LIBSUFFIX'] = '.a' |
+ env['SHLIBPREFIX'] = '$LIBPREFIX' |
+ env['SHLIBSUFFIX'] = '.so' |
+ env['LIBPREFIXES'] = [ '$LIBPREFIX' ] |
+ env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ] |
+ env['PSPAWN'] = pspawn |
+ env['SPAWN'] = spawn |
+ env['SHELL'] = 'sh' |
+ env['ESCAPE'] = escape |
+ env['TEMPFILE'] = TempFileMunge |
+ env['TEMPFILEPREFIX'] = '@' |
+ #Based on LINUX: ARG_MAX=ARG_MAX=131072 - 3000 for environment expansion |
+ #Note: specific platforms might rise or lower this value |
+ env['MAXLINELENGTH'] = 128072 |
+ |
+ # This platform supports RPATH specifications. |
+ env['__RPATH'] = '$_RPATH' |
+ |
+# Local Variables: |
+# tab-width:4 |
+# indent-tabs-mode:nil |
+# End: |
+# vim: set expandtab tabstop=4 shiftwidth=4: |
Property changes on: scons-2.0.1/engine/SCons/Platform/posix.py |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |