示例#1
0
def wait_execute(proc,
                 exit_on_error,
                 capture_output=True,
                 print_output=True,
                 timeout=None,
                 stdout_transformer=None,
                 stderr_transformer=None,
                 read_buffer_length=DEFAULT_READ_BUFFER_LENGTH):
    """Looks after a command as it runs, and prints/returns its output after."""
    if stdout_transformer is None:
        stdout_transformer = output_transformer.Hidden()

    if stderr_transformer is None:
        stderr_transformer = output_transformer.Identity()

    logger.debug('---------------------------------------')
    wait_timeout(proc, timeout)

    output_chunks = []
    stdout_transformer.set_output(sys.stdout)
    stderr_transformer.set_output(sys.stderr)

    # Stdout is printed as the process runs because some commands (e.g. ninja)
    # might take a long time to run.
    for chunk in iter(lambda: proc.stdout.read(read_buffer_length), b''):
        if print_output:
            local_logging.send_output(chunk)
            stdout_transformer.process(chunk)
        if capture_output:
            # According to: http://stackoverflow.com/questions/19926089, this is the
            # fastest way to build strings.
            output_chunks.append(chunk)

    # We cannot read from stderr because it might cause a hang.
    # Therefore, we use communicate() to get stderr instead.
    # See: https://github.com/google/clusterfuzz-tools/issues/278
    stdout_data, stderr_data = proc.communicate()
    stdout_data = stdout_data or ''
    stderr_data = stderr_data or ''
    kill(proc)

    for (transformer, data) in [(stdout_transformer, stdout_data),
                                (stderr_transformer, stderr_data)]:
        if capture_output:
            output_chunks.append(data)

        if print_output:
            local_logging.send_output(data)
            transformer.process(data)
            transformer.flush()

    logger.debug('---------------------------------------')
    if proc.returncode != 0:
        logger.debug('| Return code is non-zero (%d).', proc.returncode)
        if exit_on_error:
            logger.debug('| Exit.')
            raise error.CommandFailedError(proc.args, proc.returncode,
                                           stderr_data)
    return proc.returncode, ''.join(output_chunks)
示例#2
0
def wait_execute(proc,
                 exit_on_error,
                 capture_output=True,
                 print_output=True,
                 timeout=None,
                 ninja_command=False):
    """Looks after a command as it runs, and prints/returns its output after."""
    def _print(s):
        if print_output:
            logger.debug(s)

    _print('---------------------------------------')
    output_chunks = []
    current_line = []
    wait_timeout(proc, timeout)
    for chunk in iter(lambda: proc.stdout.read(100), b''):
        if print_output:
            local_logging.send_output(chunk)
            if ninja_command and not DEBUG_PRINT:
                for x in chunk:
                    if x == '\n':
                        interpret_ninja_output(''.join(current_line))
                        current_line = []
                    else:
                        current_line.append(x)
            elif not DEBUG_PRINT:
                sys.stdout.write('.')
                sys.stdout.flush()
        if capture_output:
            # According to: http://stackoverflow.com/questions/19926089, this is the
            # fastest way to build strings.
            output_chunks.append(chunk)
    proc.wait()
    if print_output:
        print()
    _print('---------------------------------------')
    if proc.returncode != 0:
        _print('| Return code is non-zero (%d).' % proc.returncode)
        if exit_on_error:
            _print('| Exit.')
            sys.exit(proc.returncode)
    return proc.returncode, ''.join(output_chunks)