import SCons.Node.FS
from SCons.Util import PathList, scons_str2nodes, scons_subst, scons_subst_list, autogenerate
import string
+import sys
import types
from UserList import UserList
from UserDict import UserDict
pass
+exitvalmap = {
+ 2 : 127,
+ 13 : 126,
+}
if os.name == 'posix':
pid = os.fork()
if not pid:
# Child process.
- os.execvpe(cmd, args, env)
+ exitval = 127
+ try:
+ os.execvpe(cmd, 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)
def spawn(cmd, args, env):
try:
- ret = os.spawnvpe(os.P_WAIT, cmd, args, env)
- except AttributeError:
- cmd = pathsearch(cmd, env)
- ret = os.spawnve(os.P_WAIT, cmd, args, env)
+ try:
+ ret = os.spawnvpe(os.P_WAIT, cmd, args, env)
+ except AttributeError:
+ cmd = pathsearch(cmd, env)
+ ret = os.spawnve(os.P_WAIT, cmd, args, env)
+ except OSError, e:
+ ret = exitvalmap[e[0]]
+ sys.stderr.write("scons: %s: %s\n" % (cmd, e[1]))
return ret
import TestCmd
import SCons.Builder
+import SCons.Errors
# Initial setup of the common environment for all tests,
# a temporary working directory containing a
containing one of each.
"""
+ def MyBuilder(**kw):
+ builder = apply(SCons.Builder.Builder, (), kw)
+ def no_show(str):
+ pass
+ builder.action.show = no_show
+ return builder
+
python = sys.executable
cmd1 = r'%s %s %s xyzzy' % (python, act_py, outfile)
- builder = SCons.Builder.Builder(action = cmd1)
+ builder = MyBuilder(action = cmd1)
r = builder.execute()
assert r == 0
c = test.read(outfile, 'r')
cmd2 = r'%s %s %s $TARGET' % (python, act_py, outfile)
- builder = SCons.Builder.Builder(action = cmd2)
+ builder = MyBuilder(action = cmd2)
r = builder.execute(target = 'foo')
assert r == 0
c = test.read(outfile, 'r')
cmd3 = r'%s %s %s ${TARGETS}' % (python, act_py, outfile)
- builder = SCons.Builder.Builder(action = cmd3)
+ builder = MyBuilder(action = cmd3)
r = builder.execute(target = ['aaa', 'bbb'])
assert r == 0
c = test.read(outfile, 'r')
cmd4 = r'%s %s %s $SOURCES' % (python, act_py, outfile)
- builder = SCons.Builder.Builder(action = cmd4)
+ builder = MyBuilder(action = cmd4)
r = builder.execute(source = ['one', 'two'])
assert r == 0
c = test.read(outfile, 'r')
cmd4 = r'%s %s %s ${SOURCES[:2]}' % (python, act_py, outfile)
- builder = SCons.Builder.Builder(action = cmd4)
+ builder = MyBuilder(action = cmd4)
r = builder.execute(source = ['three', 'four', 'five'])
assert r == 0
c = test.read(outfile, 'r')
cmd5 = r'%s %s %s $TARGET XYZZY' % (python, act_py, outfile)
- builder = SCons.Builder.Builder(action = cmd5)
+ builder = MyBuilder(action = cmd5)
r = builder.execute(target = 'out5', env = {'ENV' : {'XYZZY' : 'xyzzy'}})
assert r == 0
c = test.read(outfile, 'r')
cmd6 = r'%s %s %s ${TARGETS[1]} $TARGET ${SOURCES[:2]}' % (python, act_py, outfile)
- builder = SCons.Builder.Builder(action = cmd6)
+ builder = MyBuilder(action = cmd6)
r = builder.execute(target = [Obj('111'), Obj('222')],
source = [Obj('333'), Obj('444'), Obj('555')])
assert r == 0
expect7 = '%s %s %s one\n%s %s %s two\n' % (python, act_py, outfile,
python, act_py, outfile)
- builder = SCons.Builder.Builder(action = cmd7)
+ builder = MyBuilder(action = cmd7)
global show_string
show_string = ""
open(kw['target'], 'w').write("function1\n")
return 1
- builder = SCons.Builder.Builder(action = function1)
+ builder = MyBuilder(action = function1)
r = builder.execute(target = outfile)
assert r == 1
c = test.read(outfile, 'r')
def __init__(self, **kw):
open(kw['out'], 'w').write("class1a\n")
- builder = SCons.Builder.Builder(action = class1a)
+ builder = MyBuilder(action = class1a)
r = builder.execute(out = outfile)
assert r.__class__ == class1a
c = test.read(outfile, 'r')
open(kw['out'], 'w').write("class1b\n")
return 2
- builder = SCons.Builder.Builder(action = class1b())
+ builder = MyBuilder(action = class1b())
r = builder.execute(out = outfile)
assert r == 2
c = test.read(outfile, 'r')
def __init__(self, **kw):
open(kw['out'], 'a').write("class2b\n")
- builder = SCons.Builder.Builder(action = [cmd2, function2, class2a(), class2b])
+ builder = MyBuilder(action = [cmd2, function2, class2a(), class2b])
r = builder.execute(out = outfile)
assert r.__class__ == class2b
c = test.read(outfile, 'r')
assert c == "act.py: 'syzygy'\nfunction2\nclass2a\nclass2b\n", c
+ # Test that a nonexistent command returns 127
+ builder = MyBuilder(action = python + "_XyZzY_")
+ r = builder.execute(out = outfile)
+ assert r == 127, "r == %d" % r
+
+ if os.name == 'nt':
+ # NT treats execs of directories and non-executable files
+ # as "file not found" errors
+ expect = 127
+ else:
+ expect = 126
+
+ # Test that trying to execute a directory returns 126
+ dir, tail = os.path.split(python)
+ builder = MyBuilder(action = dir)
+ r = builder.execute(out = outfile)
+ assert r == expect, "r == %d" % r
+
+ # Test that trying to execute a non-executable file returns 126
+ builder = MyBuilder(action = outfile)
+ r = builder.execute(out = outfile)
+ assert r == expect, "r == %d" % r
+
def test_get_contents(self):
"""Test returning the signature contents of a Builder
"""
--- /dev/null
+#!/usr/bin/env python
+#
+# Copyright (c) 2001 Steven Knight
+#
+# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os
+import os.path
+import TestCmd
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+no_such_file = test.workpath("no_such_file")
+not_executable = test.workpath("not_executable")
+
+test.write(not_executable, "\n")
+
+test.write("f1.in", "\n")
+test.write("f2.in", "\n")
+test.write("f3.in", "\n")
+
+test.write('SConstruct1', r"""
+bld = Builder(name = 'bld', action = '%s $SOURCES $TARGET')
+env = Environment(BUILDERS = [bld])
+env.bld(target = 'f1', source = 'f1.in')
+""" % os.path.normpath(no_such_file))
+
+test.run(arguments='-f SConstruct1 .',
+ stdout = "%s f1.in f1\n" % no_such_file,
+ stderr = """scons: %s: No such file or directory
+scons: *** [f1] Error 127
+""" % no_such_file)
+
+test.write('SConstruct2', r"""
+bld = Builder(name = 'bld', action = '%s $SOURCES $TARGET')
+env = Environment(BUILDERS = [bld])
+env.bld(target = 'f2', source = 'f2.in')
+""" % os.path.normpath(not_executable))
+
+if os.name == 'nt':
+ expect = """scons: %s: No such file or directory
+scons: *** [f2] Error 127
+""" % not_executable
+else:
+ expect = """scons: %s: Permission denied
+scons: *** [f2] Error 126
+""" % not_executable
+
+test.run(arguments='-f SConstruct2 .',
+ stdout = "%s f2.in f2\n" % not_executable,
+ stderr = expect)
+
+test.write('SConstruct3', r"""
+bld = Builder(name = 'bld', action = '%s $SOURCES $TARGET')
+env = Environment(BUILDERS = [bld])
+env.bld(target = 'f3', source = 'f3.in')
+""" % os.path.normpath(test.workdir))
+
+test.run(arguments='-f SConstruct3 .',
+ stdout = "%s f3.in f3\n" % test.workdir,
+ stderr = """scons: %s: Permission denied
+scons: *** [f3] Error 126
+""" % test.workdir)
+
+test.pass_test()