|  | #!/usr/bin/env python | 
|  | # | 
|  | # Copyright 2012 the V8 project authors. All rights reserved. | 
|  | # Redistribution and use in source and binary forms, with or without | 
|  | # modification, are permitted provided that the following conditions are | 
|  | # met: | 
|  | # | 
|  | #     * Redistributions of source code must retain the above copyright | 
|  | #       notice, this list of conditions and the following disclaimer. | 
|  | #     * Redistributions in binary form must reproduce the above | 
|  | #       copyright notice, this list of conditions and the following | 
|  | #       disclaimer in the documentation and/or other materials provided | 
|  | #       with the distribution. | 
|  | #     * Neither the name of Google Inc. nor the names of its | 
|  | #       contributors may be used to endorse or promote products derived | 
|  | #       from this software without specific prior written permission. | 
|  | # | 
|  | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|  | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|  | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
|  | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
|  | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
|  | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
|  | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|  | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|  | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|  | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|  | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  |  | 
|  | # This script executes the passed command line on Android device | 
|  | # using 'adb shell' command. Unfortunately, 'adb shell' always | 
|  | # returns exit code 0, ignoring the exit code of executed command. | 
|  | # Since we need to return non-zero exit code if the command failed, | 
|  | # we augment the passed command line with exit code checking statement | 
|  | # and output special error string in case of non-zero exit code. | 
|  | # Then we parse the output of 'adb shell' and look for that error string. | 
|  |  | 
|  | import os | 
|  | from os.path import join, dirname, abspath | 
|  | import subprocess | 
|  | import sys | 
|  | import tempfile | 
|  |  | 
|  | def Check(output, errors): | 
|  | failed = any([s.startswith('/system/bin/sh:') or s.startswith('ANDROID') | 
|  | for s in output.split('\n')]) | 
|  | return 1 if failed else 0 | 
|  |  | 
|  | def Execute(cmdline): | 
|  | (fd_out, outname) = tempfile.mkstemp() | 
|  | (fd_err, errname) = tempfile.mkstemp() | 
|  | process = subprocess.Popen( | 
|  | args=cmdline, | 
|  | shell=True, | 
|  | stdout=fd_out, | 
|  | stderr=fd_err, | 
|  | ) | 
|  | exit_code = process.wait() | 
|  | os.close(fd_out) | 
|  | os.close(fd_err) | 
|  | output = file(outname).read() | 
|  | errors = file(errname).read() | 
|  | os.unlink(outname) | 
|  | os.unlink(errname) | 
|  | sys.stdout.write(output) | 
|  | sys.stderr.write(errors) | 
|  | return exit_code or Check(output, errors) | 
|  |  | 
|  | def Escape(arg): | 
|  | def ShouldEscape(): | 
|  | for x in arg: | 
|  | if not x.isalnum() and x != '-' and x != '_': | 
|  | return True | 
|  | return False | 
|  |  | 
|  | return arg if not ShouldEscape() else '"%s"' % (arg.replace('"', '\\"')) | 
|  |  | 
|  | def WriteToTemporaryFile(data): | 
|  | (fd, fname) = tempfile.mkstemp() | 
|  | os.close(fd) | 
|  | tmp_file = open(fname, "w") | 
|  | tmp_file.write(data) | 
|  | tmp_file.close() | 
|  | return fname | 
|  |  | 
|  | def Main(): | 
|  | if (len(sys.argv) == 1): | 
|  | print("Usage: %s <command-to-run-on-device>" % sys.argv[0]) | 
|  | return 1 | 
|  | workspace = abspath(join(dirname(sys.argv[0]), '..')) | 
|  | v8_root = "/data/local/tmp/v8" | 
|  | android_workspace = os.getenv("ANDROID_V8", v8_root) | 
|  | args = [Escape(arg) for arg in sys.argv[1:]] | 
|  | script = (" ".join(args) + "\n" | 
|  | "case $? in\n" | 
|  | "  0) ;;\n" | 
|  | "  *) echo \"ANDROID: Error returned by test\";;\n" | 
|  | "esac\n") | 
|  | script = script.replace(workspace, android_workspace) | 
|  | script_file = WriteToTemporaryFile(script) | 
|  | android_script_file = android_workspace + "/" + script_file | 
|  | command =  ("adb push '%s' %s;" % (script_file, android_script_file) + | 
|  | "adb shell 'cd %s && sh %s';" % (v8_root, android_script_file) + | 
|  | "adb shell 'rm %s'" % android_script_file) | 
|  | error_code = Execute(command) | 
|  | os.unlink(script_file) | 
|  | return error_code | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | sys.exit(Main()) |