<s> import subprocess <EOL> import threading <EOL> import os <EOL> import signal <EOL> import sys <EOL> import time <EOL> import traceback <EOL> from functools import partial <EOL> from sts . util . console import color <EOL> def split_up ( f , l ) : <EOL> trues = [ ] <EOL> falses = [ ] <EOL> for elem in l : <EOL> if ( f ( elem ) ) : <EOL> trues . append ( elem ) <EOL> else : <EOL> falses . append ( elem ) <EOL> return ( trues , falses ) <EOL> def kill_procs ( child_processes , kill = None , verbose = True , timeout = <NUM_LIT:5> , <EOL> close_fds = True ) : <EOL> child_processes = filter ( lambda e : e is not None , child_processes ) <EOL> def msg ( msg ) : <EOL> if ( verbose ) : <EOL> sys . stderr . write ( msg ) <EOL> if kill == None : <EOL> if hasattr ( kill_procs , "<STR_LIT>" ) : <EOL> kill = True <EOL> else : <EOL> kill = False <EOL> kill_procs . already_run = True <EOL> if len ( child_processes ) == <NUM_LIT:0> : <EOL> return <EOL> msg ( "<STR_LIT>" % ( "<STR_LIT>" if kill else "<STR_LIT>" ) ) <EOL> for child in child_processes : <EOL> sig = signal . SIGKILL if kill else signal . SIGTERM <EOL> pgid = os . getpgid ( child . pid ) <EOL> if pgid == child . pid : <EOL> os . killpg ( pgid , sig ) <EOL> else : <EOL> os . kill ( child . pid , sig ) <EOL> start_time = time . time ( ) <EOL> last_dot = start_time <EOL> all_dead = [ ] <EOL> while True : <EOL> ( child_processes , new_dead ) = split_up ( lambda child : child . poll ( ) is None , child_processes ) <EOL> all_dead += new_dead <EOL> if len ( child_processes ) == <NUM_LIT:0> : <EOL> break <EOL> if hasattr ( time , "<STR_LIT>" ) : <EOL> time . _orig_sleep ( <NUM_LIT:0.1> ) <EOL> else : <EOL> time . sleep ( <NUM_LIT:0.1> ) <EOL> now = time . time ( ) <EOL> if ( now - last_dot ) > <NUM_LIT:1> : <EOL> msg ( "<STR_LIT:.>" ) <EOL> last_dot = now <EOL> if ( now - start_time ) > timeout : <EOL> if kill : <EOL> break <EOL> else : <EOL> msg ( '<STR_LIT>' ) <EOL> kill_procs ( child_processes , kill = True ) <EOL> break <EOL> if close_fds : <EOL> for child in all_dead : <EOL> for attr_name in "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" : <EOL> if hasattr ( child , attr_name ) : <EOL> try : <EOL> attr = getattr ( child , attr_name ) <EOL> if attr : <EOL> attr . close ( ) <EOL> except IOError : <EOL> msg ( "<STR_LIT>" % attr_name ) <EOL> except : <EOL> msg ( "<STR_LIT>" ) <EOL> tb = traceback . format_exc ( ) <EOL> msg ( tb ) <EOL> if len ( child_processes ) == <NUM_LIT:0> : <EOL> msg ( '<STR_LIT>' ) <EOL> printlock = threading . Lock ( ) <EOL> def _prefix_thread ( f , func ) : <EOL> def run ( ) : <EOL> while not f . closed : <EOL> line = f . readline ( ) <EOL> if not line : <EOL> break <EOL> with printlock : <EOL> print func ( line ) <EOL> try : <EOL> sys . stderr . write ( "<STR_LIT>" % f ) <EOL> f . close ( ) <EOL> except : <EOL> pass <EOL> t = threading . Thread ( target = run ) <EOL> t . daemon = True <EOL> t . start ( ) <EOL> return t <EOL> def color_normal ( out_str , label ) : <EOL> """<STR_LIT>""" <EOL> return "<STR_LIT>" % ( color . YELLOW , label , out_str . rstrip ( ) , color . NORMAL ) <EOL> def color_error ( out_str , label ) : <EOL> """<STR_LIT>""" <EOL> return "<STR_LIT>" % ( color . B_RED + color . YELLOW , label , out_str . rstrip ( ) , <EOL> color . NORMAL ) <EOL> def popen_filtered ( name , args , cwd = None , env = None , redirect_output = True , <EOL> shell = False ) : <EOL> if shell and type ( args ) == list : <EOL> args = '<STR_LIT:U+0020>' . join ( args ) <EOL> try : <EOL> cmd = subprocess . Popen ( args , stdout = subprocess . PIPE , shell = shell , <EOL> stderr = subprocess . PIPE , stdin = sys . stdin , cwd = cwd , env = env , <EOL> preexec_fn = lambda : os . setsid ( ) ) <EOL> except OSError as e : <EOL> raise OSError ( "<STR_LIT>" % ( args , cwd , e . strerror , e . errno ) ) <EOL> if redirect_output : <EOL> cmd . _stdout_thread = _prefix_thread ( cmd . stdout , partial ( color_normal , label = name ) ) <EOL> cmd . _stderr_thread = _prefix_thread ( cmd . stderr , partial ( color_error , label = name ) ) <EOL> return cmd </s>
