in tools/android/emulator/common.py [0:0]
def Spawn(args, proc_input=None, proc_output=None, exec_dir=None,
exec_env=None, logfile=None, **kwargs):
"""Execs a subprocess using Popen.
Task output will be logged to file.
Args:
args: A list of arguments to execute
proc_input: takes true or a file descriptor. If true the stdin is a
readable pipe. If file descriptor the file is piped into stdin
proc_output: true for stdout/stderr to be pipes, file descriptor to pipe to
file.
exec_dir: the directory the subprocess will run from.
exec_env: the environment the subprocess will use.
logfile: an optional filename to log stdout/stderr.
**kwargs: passed to subprocess.Popen as is.
Returns:
An object supporting Popen.wait(), Popen.stdout and Popen.stdin
"""
proc_err = proc_output
if not exec_dir:
exec_dir = os.getcwd()
if not exec_env:
exec_env = dict(os.environ)
if not logfile:
logfile = CommandLogFile(args, exec_dir, exec_env)
if not logfile:
logfile = '/dev/null'
logfile_handle = None
if proc_input == True: # could be a file or True or none
proc_input = subprocess.PIPE
logged_to_file = False
if proc_output == True: # could be a file or True or None
proc_output = subprocess.PIPE
proc_err = subprocess.PIPE
elif not proc_output:
# caller not doing anything with outputs, dont pass them on.
# just write output straight to log.
logged_to_file = True
logfile_handle = open(logfile, 'a')
proc_output = logfile_handle
proc_err = logfile_handle
logging.debug('Launching %s. input: %s, output: %s, execdir: %s',
' '.join(args), proc_input, proc_output, exec_dir)
task = None
if not logged_to_file:
# launch the task and tee tasks to write the stdout/stderr to file and then
# pass it along to the caller's pipes or files.
task = subprocess.Popen(args, stdout=subprocess.PIPE, stdin=proc_input,
env=exec_env, cwd=exec_dir, stderr=subprocess.PIPE,
close_fds=True,
**kwargs)
log_out_task = subprocess.Popen(_GetLogCommand(logfile),
stdin=task.stdout, stdout=proc_output,
stderr=open('/dev/null'),
close_fds=True)
log_err_task = subprocess.Popen(_GetLogCommand(logfile, is_stderr=True),
stdin=task.stderr, stdout=proc_err,
stderr=open('/dev/null'),
close_fds=True)
task.stdout = log_out_task.stdout
task.stderr = log_err_task.stdout
task.tee_stdout_task = log_out_task
task.tee_stderr_task = log_err_task
else:
# proc_output and proc_error are already pointing to the logfiles.
task = subprocess.Popen(args, stdout=proc_output, stdin=proc_input,
env=exec_env, cwd=exec_dir, stderr=proc_err,
close_fds=True)
task.logfile_handle = logfile_handle
task.logged_stdout = ''
task.logged_stderr = ''
task.spawn_env = exec_env
def LoggingCommunicate(task_in=None):
"""Used to capture the results of a call to communicate.
Args:
task_in: optional input to communicate
Returns:
A pair of (stdout, stderr) from the process.
"""
task.logged_stdout, task.logged_stderr = task.RawCommunicate(input=task_in)
return (task.logged_stdout, task.logged_stderr)
task.RawCommunicate = task.communicate
task.communicate = LoggingCommunicate
return task