summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2002-08-23 02:14:44 (GMT)
committerSteven Knight <knight@baldmt.com>2002-08-23 02:14:44 (GMT)
commit62446cb66567e967e1af2b6a0c152fdeb98508c8 (patch)
tree74ac1c6836dbf3b614aef7c1ce2a2c7b5291cee0
parentd7079b4271cc358b515378e8b02bdf52637f3ee0 (diff)
downloadSCons-62446cb66567e967e1af2b6a0c152fdeb98508c8.zip
SCons-62446cb66567e967e1af2b6a0c152fdeb98508c8.tar.gz
SCons-62446cb66567e967e1af2b6a0c152fdeb98508c8.tar.bz2
Implement spawn() using os.system() on Posix OSes. (Anthony Roach)
-rw-r--r--src/CHANGES.txt4
-rw-r--r--src/engine/SCons/Action.py62
-rw-r--r--test/DVIPDF.py3
-rw-r--r--test/DVIPDFFLAGS.py3
-rw-r--r--test/F77PATH.py6
5 files changed, 55 insertions, 23 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index fb8196e..80a0db6 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -32,6 +32,10 @@ RELEASE 0.09 -
- Fix differently ordered targets causing unnecessary rebuilds
on case insensitive systems.
+ - Use os.system() to execute external commands whenever the "env"
+ utility is available, which is much faster than fork()/exec(),
+ and fixes the -j option on several platforms.
+
RELEASE 0.08 - Mon, 15 Jul 2002 12:08:51 -0500
diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py
index e2fe07f..7aecf00 100644
--- a/src/engine/SCons/Action.py
+++ b/src/engine/SCons/Action.py
@@ -58,23 +58,51 @@ def quote(x):
if os.name == 'posix':
- def defaultSpawn(cmd, args, env):
- pid = os.fork()
- if not pid:
- # Child process.
- exitval = 127
- args = ['sh', '-c', string.join(map(quote, args))]
- try:
- os.execvpe('sh', args, env)
- except OSError, e:
- exitval = exitvalmap[e[0]]
- sys.stderr.write("scons: %s: %s\n" % (cmd, e[1]))
- os._exit(exitval)
- else:
- # Parent process.
- pid, stat = os.waitpid(pid, 0)
- ret = stat >> 8
- return ret
+ def escape(arg):
+ "escape shell special characters"
+ slash = '\\'
+ special = '"\'`&;><| \t#()*?$~!'
+
+ arg = string.replace(arg, slash, slash+slash)
+ for c in special:
+ arg = string.replace(arg, c, slash+c)
+
+ return arg
+
+ # If the env command exists, then we can use os.system()
+ # to spawn commands, otherwise we fall back on os.fork()/os.exec().
+ # os.system() is prefered because it seems to work better with
+ # threads (i.e. -j) and is more efficient than forking Python.
+ if SCons.Util.WhereIs('env'):
+ def defaultSpawn(cmd, args, env):
+ if env:
+ s = 'env -i '
+ for key in env.keys():
+ s = s + '%s=%s '%(key, escape(env[key]))
+ s = s + 'sh -c '
+ s = s + escape(string.join(map(quote, args)))
+ else:
+ s = string.join(map(quote, args))
+
+ return os.system(s) >> 8
+ else:
+ def defaultSpawn(cmd, args, env):
+ pid = os.fork()
+ if not pid:
+ # Child process.
+ exitval = 127
+ args = ['sh', '-c', string.join(map(quote, args))]
+ try:
+ os.execvpe('sh', args, env)
+ except OSError, e:
+ exitval = exitvalmap[e[0]]
+ sys.stderr.write("scons: %s: %s\n" % (cmd, e[1]))
+ os._exit(exitval)
+ else:
+ # Parent process.
+ pid, stat = os.waitpid(pid, 0)
+ ret = stat >> 8
+ return ret
elif os.name == 'nt':
diff --git a/test/DVIPDF.py b/test/DVIPDF.py
index d22cfd8..25856dc 100644
--- a/test/DVIPDF.py
+++ b/test/DVIPDF.py
@@ -100,8 +100,9 @@ test.fail_test(test.read('test2.pdf') != "This is a .tex test.\n")
dvipdf = test.where_is('dvipdf')
+tex = test.where_is('tex')
-if dvipdf:
+if dvipdf and tex:
test.write("wrapper.py", """import os
import string
diff --git a/test/DVIPDFFLAGS.py b/test/DVIPDFFLAGS.py
index e6f9146..9962253 100644
--- a/test/DVIPDFFLAGS.py
+++ b/test/DVIPDFFLAGS.py
@@ -106,8 +106,9 @@ test.fail_test(test.read('test2.pdf') != " -x\nThis is a .tex test.\n")
dvipdf = test.where_is('dvipdf')
+tex = test.where_is('tex')
-if dvipdf:
+if dvipdf and tex:
test.write("wrapper.py", """import os
import string
diff --git a/test/F77PATH.py b/test/F77PATH.py
index ad38bf1..3dcc280 100644
--- a/test/F77PATH.py
+++ b/test/F77PATH.py
@@ -42,10 +42,8 @@ args = prog + ' ' + subdir_prog + ' ' + variant_prog
test = TestSCons.TestSCons()
if not test.where_is('g77'):
- print "g77 is not installed on this system."
- print "Cannot test F77PATH."
- test.no_result(1)
-
+ test.pass_test()
+
test.subdir('include', 'subdir', ['subdir', 'include'], 'inc2')
test.write('SConstruct', """