Implement spawn() using os.system() on Posix OSes. (Anthony Roach)
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 23 Aug 2002 02:14:44 +0000 (02:14 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 23 Aug 2002 02:14:44 +0000 (02:14 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@444 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Action.py
test/DVIPDF.py
test/DVIPDFFLAGS.py
test/F77PATH.py

index fb8196e001fe67a618dfee36111a885c6acec341..80a0db60d25b7b1250590b53defc2c6b4d13220e 100644 (file)
@@ -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
index e2fe07f0fa4a755e4ed5b4275d4244c832172536..7aecf00167d27248a288fca81a2324d18f405c84 100644 (file)
@@ -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':
 
index d22cfd8bc8c7913507fa38fb80fcdfa311c4a6a8..25856dcab2776b30602f3aabfb5878a69449266f 100644 (file)
@@ -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
index e6f91463964684ce99b3901a027058dabb07a20a..9962253646fc4a9b1259536c9b1102ff936f6d48 100644 (file)
@@ -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
index ad38bf1f6e5cce1ea1127ab216245c101a813221..3dcc2804b93ddaa458b521e14f9a24f02deddfe5 100644 (file)
@@ -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', """