This reverts commit 96c957ae20
.
Fixes issues on some machines where the socket in TMPDIR ended up with a
unix domain socket pathname over 107 characters long, which Go will
reject due to underlying limitations in the system calls. If this
happens, we'll fall back to opening the directory, then using
/proc/self/fd/#/<file>, or manually creating a similar symlink in /tmp.
Also fixes some issues on Mac where os.Executable returns the symlink
instead of the underlying file, sending a message over a unix domain
socket will block if the reader isn't reading, and sandboxing was
preventing us from running `ps`.
Test: m blueprint_tools
Test: m blueprint_tools on mac
Change-Id: Ib19ccfe10cb0a79f1476fb1d5cd20ed0495be367
90 lines
2.5 KiB
Python
90 lines
2.5 KiB
Python
#!/usr/bin/env python
|
|
|
|
import os
|
|
import re
|
|
import tempfile
|
|
import shutil
|
|
import sys
|
|
import subprocess
|
|
import zipfile
|
|
|
|
PYTHON_BINARY = '%interpreter%'
|
|
MAIN_FILE = '%main%'
|
|
PYTHON_PATH = 'PYTHONPATH'
|
|
ZIP_RUNFILES_DIRECTORY_NAME = 'runfiles'
|
|
|
|
def SearchPathEnv(name):
|
|
search_path = os.getenv('PATH', os.defpath).split(os.pathsep)
|
|
for directory in search_path:
|
|
if directory == '': continue
|
|
path = os.path.join(directory, name)
|
|
# Check if path is actual executable file.
|
|
if os.path.isfile(path) and os.access(path, os.X_OK):
|
|
return path
|
|
return None
|
|
|
|
def FindPythonBinary():
|
|
if PYTHON_BINARY.startswith('/'):
|
|
# Case 1: Python interpreter is directly provided with absolute path.
|
|
return PYTHON_BINARY
|
|
else:
|
|
# Case 2: Find Python interpreter through environment variable: PATH.
|
|
return SearchPathEnv(PYTHON_BINARY)
|
|
|
|
# Create the runfiles tree by extracting the zip file
|
|
def ExtractRunfiles():
|
|
temp_dir = tempfile.mkdtemp("", "Soong.python_")
|
|
zf = zipfile.ZipFile(os.path.dirname(__file__))
|
|
zf.extractall(temp_dir)
|
|
return os.path.join(temp_dir, ZIP_RUNFILES_DIRECTORY_NAME)
|
|
|
|
def Main():
|
|
args = sys.argv[1:]
|
|
|
|
new_env = {}
|
|
|
|
try:
|
|
runfiles_path = ExtractRunfiles()
|
|
|
|
# Add runfiles path to PYTHONPATH.
|
|
python_path_entries = [runfiles_path]
|
|
|
|
# Add top dirs within runfiles path to PYTHONPATH.
|
|
top_entries = [os.path.join(runfiles_path, i) for i in os.listdir(runfiles_path)]
|
|
top_pkg_dirs = [i for i in top_entries if os.path.isdir(i)]
|
|
python_path_entries += top_pkg_dirs
|
|
|
|
old_python_path = os.environ.get(PYTHON_PATH)
|
|
separator = ':'
|
|
new_python_path = separator.join(python_path_entries)
|
|
|
|
# Copy old PYTHONPATH.
|
|
if old_python_path:
|
|
new_python_path += separator + old_python_path
|
|
new_env[PYTHON_PATH] = new_python_path
|
|
|
|
# Now look for main python source file.
|
|
main_filepath = os.path.join(runfiles_path, MAIN_FILE)
|
|
assert os.path.exists(main_filepath), \
|
|
'Cannot exec() %r: file not found.' % main_filepath
|
|
assert os.access(main_filepath, os.R_OK), \
|
|
'Cannot exec() %r: file not readable.' % main_filepath
|
|
|
|
python_program = FindPythonBinary()
|
|
if python_program is None:
|
|
raise AssertionError('Could not find python binary: ' + PYTHON_BINARY)
|
|
args = [python_program, main_filepath] + args
|
|
|
|
os.environ.update(new_env)
|
|
|
|
sys.stdout.flush()
|
|
retCode = subprocess.call(args)
|
|
exit(retCode)
|
|
except:
|
|
raise
|
|
finally:
|
|
shutil.rmtree(os.path.dirname(runfiles_path), True)
|
|
|
|
if __name__ == '__main__':
|
|
Main()
|