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) if len(split) > 2: while len(split) > 1: content, sep = split[:2] split = split[2:] print_clean_line(dest, pending.pop(fd, []) + [content], width, sep) else: assert(len(split) == 1) pending.setdefault(fd, []).extend(split) except BaseException as ex: pending_ex = chain_ex(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 = chain_ex(add_ex_tb(ex), pending_ex) except BaseException as ex: pending_ex = chain_ex(add_ex_tb(ex), pending_ex) if pending_ex: raise pending_ex
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) if len(split) > 2: while len(split) > 1: content, sep = split[:2] split = split[2:] print_clean_line(dest, pending.pop(fd, []) + [content], width, sep) else: assert (len(split) == 1) pending.setdefault(fd, []).extend(split) except BaseException as ex: pending_ex = chain_ex(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 = chain_ex(add_ex_tb(ex), pending_ex) except BaseException as ex: pending_ex = chain_ex(add_ex_tb(ex), pending_ex) if pending_ex: raise pending_ex
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, preexec_fn=force_tty, 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 chain_ex(add_ex_tb(kill_ex), ex) raise ex