Exemple #1
0
def filter_output(srcs, dests):
    """Transfer data from file descriptors in srcs to the corresponding
    file descriptors in dests print_clean_line until all of the srcs
    have closed.

    """
    global sep_rx
    assert all(type(x) in int_types for x in srcs)
    assert all(type(x) in int_types for x in srcs)
    assert len(srcs) == len(dests)
    srcs = tuple(srcs)
    dest_for = dict(zip(srcs, dests))
    pending = {}
    pending_ex = None
    try:
        while srcs:
            ready_fds, _, _ = select.select(srcs, [], [])
            width = tty_width()
            for fd in ready_fds:
                buf = os.read(fd, 4096)
                dest = dest_for[fd]
                if not buf:
                    srcs = tuple([x for x in srcs if x is not fd])
                    print_clean_line(dest, pending.pop(fd, []), width)
                else:
                    split = sep_rx.split(buf)
                    while len(split) > 1:
                        content, sep = split[:2]
                        split = split[2:]
                        print_clean_line(dest,
                                         pending.pop(fd, []) + [content],
                                         width,
                                         sep)
                    assert len(split) == 1
                    if split[0]:
                        pending.setdefault(fd, []).extend(split)
    except BaseException as ex:
        pending_ex = add_ex_ctx(add_ex_tb(ex), pending_ex)
    try:
        # Try to finish each of the streams
        for fd, pending_items in compat.items(pending):
            dest = dest_for[fd]
            width = tty_width()
            try:
                print_clean_line(dest, pending_items, width)
            except (EnvironmentError, EOFError) as ex:
                pending_ex = add_ex_ctx(add_ex_tb(ex), pending_ex)
    except BaseException as ex:
        pending_ex = add_ex_ctx(add_ex_tb(ex), pending_ex)
    if pending_ex:
        raise pending_ex
Exemple #2
0
def filter_output(src_out, src_err, dest_out, dest_err):
    """Transfer data from src_out to dest_out and src_err to dest_err via
    print_clean_line until src_out and src_err close."""
    global sep_rx
    assert not isinstance(src_out, bool)
    assert not isinstance(src_err, bool)
    assert not isinstance(dest_out, bool)
    assert not isinstance(dest_err, bool)
    assert src_out is not None or src_err is not None
    assert (src_out is None) == (dest_out is None)
    assert (src_err is None) == (dest_err is None)
    pending = {}
    pending_ex = None
    try:
        fds = tuple([x for x in (src_out, src_err) if x is not None])
        while fds:
            ready_fds, _, _ = select.select(fds, [], [])
            width = tty_width()
            for fd in ready_fds:
                buf = os.read(fd, 4096)
                dest = dest_out if fd == src_out else dest_err
                if not buf:
                    fds = tuple([x for x in fds if x is not fd])
                    print_clean_line(dest, pending.pop(fd, []), width)
                else:
                    split = sep_rx.split(buf)
                    while len(split) > 1:
                        content, sep = split[:2]
                        split = split[2:]
                        print_clean_line(dest,
                                         pending.pop(fd, []) + [content],
                                         width, sep)
                    assert (len(split) == 1)
                    if split[0]:
                        pending.setdefault(fd, []).extend(split)
    except BaseException as ex:
        pending_ex = add_ex_ctx(add_ex_tb(ex), pending_ex)
    try:
        # Try to finish each of the streams
        for fd, pending_items in compat.items(pending):
            dest = dest_out if fd == src_out else dest_err
            try:
                print_clean_line(dest, pending_items, width)
            except (EnvironmentError, EOFError) as ex:
                pending_ex = add_ex_ctx(add_ex_tb(ex), pending_ex)
    except BaseException as ex:
        pending_ex = add_ex_ctx(add_ex_tb(ex), pending_ex)
    if pending_ex:
        raise pending_ex
Exemple #3
0
def run_subcmd(subcmd):

    c = (do_profile and [sys.executable, '-m', 'cProfile'] or []) + subcmd
    if not (fix_stdout or fix_stderr):
        os.execvp(c[0], c)

    p = None
    try:
        p = subprocess.Popen(c,
                             stdout=PIPE if fix_stdout else sys.stdout,
                             stderr=PIPE if fix_stderr else sys.stderr,
                             env=tty_env,
                             bufsize=4096,
                             close_fds=True)
        # Assume p will receive these signals and quit, which will
        # then cause us to quit.
        for sig in (signal.SIGINT, signal.SIGTERM, signal.SIGQUIT):
            signal.signal(sig, signal.SIG_IGN)

        filter_output(fix_stdout and p.stdout.fileno() or None,
                      fix_stderr and p.stderr.fileno() or None,
                      fix_stdout and sys.stdout.fileno() or None,
                      fix_stderr and sys.stderr.fileno() or None)
        return p.wait()
    except BaseException as ex:
        add_ex_tb(ex)
        try:
            if p and p.poll() == None:
                os.kill(p.pid, signal.SIGTERM)
                p.wait()
        except BaseException as kill_ex:
            raise add_ex_ctx(add_ex_tb(kill_ex), ex)
        raise ex
Exemple #4
0
Fichier : main.py Projet : gdt/bup
def run_subproc_cmd(args):

    c = (do_profile and [sys.executable, b'-m', b'cProfile'] or []) + args
    if not (fix_stdout or fix_stderr):
        os.execvp(c[0], c)

    sys.stdout.flush()
    sys.stderr.flush()
    out = byte_stream(sys.stdout)
    err = byte_stream(sys.stderr)
    p = None
    try:
        p = subprocess.Popen(c,
                             stdout=PIPE if fix_stdout else out,
                             stderr=PIPE if fix_stderr else err,
                             env=tty_env,
                             bufsize=4096,
                             close_fds=True)
        # Assume p will receive these signals and quit, which will
        # then cause us to quit.
        for sig in (signal.SIGINT, signal.SIGTERM, signal.SIGQUIT):
            signal.signal(sig, signal.SIG_IGN)

        srcs = []
        dests = []
        if fix_stdout:
            srcs.append(p.stdout.fileno())
            dests.append(out.fileno())
        if fix_stderr:
            srcs.append(p.stderr.fileno())
            dests.append(err.fileno())
        filter_output(srcs, dests)
        return p.wait()
    except BaseException as ex:
        add_ex_tb(ex)
        try:
            if p and p.poll() == None:
                os.kill(p.pid, signal.SIGTERM)
                p.wait()
        except BaseException as kill_ex:
            raise add_ex_ctx(add_ex_tb(kill_ex), ex)
        raise ex
Exemple #5
0
def run_module_cmd(module, args):
    if not (fix_stdout or fix_stderr):
        import_and_run_main(module, args)
        return
    # Interpose filter_output between all attempts to write to the
    # stdout/stderr and the real stdout/stderr (e.g. the fds that
    # connect directly to the terminal) via a thread that runs
    # filter_output in a pipeline.
    srcs = []
    dests = []
    real_out_fd = real_err_fd = stdout_pipe = stderr_pipe = None
    filter_thread = filter_thread_started = None
    pending_ex = None
    try:
        if fix_stdout:
            sys.stdout.flush()
            stdout_pipe = os.pipe()  # monitored_by_filter, stdout_everyone_uses
            real_out_fd = os.dup(sys.stdout.fileno())
            os.dup2(stdout_pipe[1], sys.stdout.fileno())
            srcs.append(stdout_pipe[0])
            dests.append(real_out_fd)
        if fix_stderr:
            sys.stderr.flush()
            stderr_pipe = os.pipe()  # monitored_by_filter, stderr_everyone_uses
            real_err_fd = os.dup(sys.stderr.fileno())
            os.dup2(stderr_pipe[1], sys.stderr.fileno())
            srcs.append(stderr_pipe[0])
            dests.append(real_err_fd)

        filter_thread = Thread(name='output filter',
                               target=lambda : filter_output(srcs, dests))
        filter_thread.start()
        filter_thread_started = True
        import_and_run_main(module, args)
    except Exception as ex:
        add_ex_tb(ex)
        pending_ex = ex
        raise
    finally:
        # Try to make sure that whatever else happens, we restore
        # stdout and stderr here, if that's possible, so that we don't
        # risk just losing some output.
        try:
            real_out_fd is not None and os.dup2(real_out_fd, sys.stdout.fileno())
        except Exception as ex:
            add_ex_tb(ex)
            add_ex_ctx(ex, pending_ex)
        try:
            real_err_fd is not None and os.dup2(real_err_fd, sys.stderr.fileno())
        except Exception as ex:
            add_ex_tb(ex)
            add_ex_ctx(ex, pending_ex)
        # Kick filter loose
        try:
            stdout_pipe is not None and os.close(stdout_pipe[1])
        except Exception as ex:
            add_ex_tb(ex)
            add_ex_ctx(ex, pending_ex)
        try:
            stderr_pipe is not None and os.close(stderr_pipe[1])
        except Exception as ex:
            add_ex_tb(ex)
            add_ex_ctx(ex, pending_ex)
        try:
            close_catpipes()
        except Exception as ex:
            add_ex_tb(ex)
            add_ex_ctx(ex, pending_ex)
    if pending_ex:
        raise pending_ex
    # There's no point in trying to join unless we finished the finally block.
    if filter_thread_started:
        filter_thread.join()