<s> """<STR_LIT>""" <EOL> import os <EOL> import sys <EOL> import contextlib <EOL> import subprocess <EOL> import signal <EOL> import threading <EOL> import Queue <EOL> from qisys import ui <EOL> import qisys . error <EOL> import qisys . envsetter <EOL> _FIND_PROGRAM_CACHE = dict ( ) <EOL> SIGINT_EVENT = threading . Event ( ) <EOL> class Process ( object ) : <EOL> """<STR_LIT>""" <EOL> OK = <NUM_LIT:0> <EOL> FAILED = <NUM_LIT:1> <EOL> TIME_OUT = <NUM_LIT:2> <EOL> ZOMBIE = <NUM_LIT:3> <EOL> INTERRUPTED = <NUM_LIT:4> <EOL> NOT_RUN = <NUM_LIT:5> <EOL> def __init__ ( self , cmd , cwd = None , env = None , capture = True ) : <EOL> self . cmd = cmd <EOL> self . cwd = cwd <EOL> self . env = env <EOL> self . out = "<STR_LIT>" <EOL> self . returncode = None <EOL> self . _process = None <EOL> self . exception = None <EOL> self . return_type = Process . FAILED <EOL> self . capture = capture <EOL> def run ( self , timeout = None ) : <EOL> def target ( ) : <EOL> ui . debug ( "<STR_LIT>" ) <EOL> ui . debug ( "<STR_LIT>" , subprocess . list2cmdline ( self . cmd ) ) <EOL> try : <EOL> opts = dict ( ) <EOL> if os . name == '<STR_LIT>' : <EOL> opts = { <EOL> '<STR_LIT>' : os . setsid , <EOL> '<STR_LIT>' : True <EOL> } <EOL> elif os . name == '<STR_LIT>' : <EOL> opts = { <EOL> '<STR_LIT>' : subprocess . CREATE_NEW_PROCESS_GROUP , <EOL> } <EOL> kwargs = { <EOL> "<STR_LIT>" : self . cwd , <EOL> "<STR_LIT>" : self . env <EOL> } <EOL> kwargs . update ( opts ) <EOL> if self . capture : <EOL> kwargs [ "<STR_LIT>" ] = subprocess . PIPE <EOL> kwargs [ "<STR_LIT>" ] = subprocess . STDOUT <EOL> self . _process = subprocess . Popen ( self . cmd , ** kwargs ) <EOL> except Exception , e : <EOL> self . exception = e <EOL> self . return_type = Process . NOT_RUN <EOL> return <EOL> def read_target ( ) : <EOL> self . out = self . _process . communicate ( ) [ <NUM_LIT:0> ] <EOL> self . _should_stop_reading = False <EOL> self . _reading_thread = threading . Thread ( target = read_target ) <EOL> self . _reading_thread . daemon = True <EOL> self . _reading_thread . start ( ) <EOL> while not self . _should_stop_reading and self . _reading_thread . is_alive ( ) : <EOL> self . _reading_thread . join ( <NUM_LIT:1> ) <EOL> self . returncode = self . _process . returncode <EOL> if self . returncode == <NUM_LIT:0> : <EOL> ui . debug ( "<STR_LIT>" ) <EOL> self . return_type = Process . OK <EOL> ui . debug ( "<STR_LIT>" ) <EOL> self . _thread = threading . Thread ( target = target ) <EOL> self . _thread . start ( ) <EOL> while ( ( timeout is None or <NUM_LIT:0> < timeout ) and self . _thread . is_alive ( ) and <EOL> not SIGINT_EVENT . is_set ( ) ) : <EOL> self . _thread . join ( <NUM_LIT:1> ) <EOL> if timeout is not None : <EOL> timeout -= <NUM_LIT:1> <EOL> if not self . _thread . is_alive ( ) : <EOL> return <EOL> elif SIGINT_EVENT . is_set ( ) : <EOL> self . _interrupt ( ) <EOL> else : <EOL> ui . debug ( "<STR_LIT>" ) <EOL> self . _kill_subprocess ( ) <EOL> def _kill_subprocess ( self ) : <EOL> if self . _thread and self . _process : <EOL> self . return_type = Process . TIME_OUT <EOL> ui . debug ( "<STR_LIT>" ) <EOL> try : <EOL> self . _process . terminate ( ) <EOL> except Exception : <EOL> pass <EOL> ui . debug ( "<STR_LIT>" ) <EOL> self . _thread . join ( <NUM_LIT:5> ) <EOL> if self . _thread . is_alive ( ) : <EOL> ui . debug ( "<STR_LIT>" ) <EOL> self . _destroy_zombie ( ) <EOL> def _interrupt ( self ) : <EOL> if self . _process and self . _thread . is_alive ( ) : <EOL> self . _destroy_zombie ( ) <EOL> self . return_type = Process . INTERRUPTED <EOL> def _destroy_zombie ( self ) : <EOL> if not self . _process : <EOL> pass <EOL> elif os . name == '<STR_LIT>' : <EOL> os . killpg ( self . _process . pid , signal . SIGKILL ) <EOL> elif os . name == '<STR_LIT>' : <EOL> os . kill ( self . _process . pid , signal . CTRL_BREAK_EVENT ) <EOL> self . return_type = Process . ZOMBIE <EOL> self . _should_stop_reading = True <EOL> self . _thread . join ( ) <EOL> def str_from_signal ( code ) : <EOL> """<STR_LIT>""" <EOL> if os . name == "<STR_LIT>" : <EOL> value = <NUM_LIT:2> ** <NUM_LIT:32> - code <EOL> as_str = "<STR_LIT>" % ( value ) <EOL> if value == <NUM_LIT> : <EOL> return "<STR_LIT>" % as_str <EOL> else : <EOL> return as_str <EOL> if code == signal . SIGSEGV : <EOL> return "<STR_LIT>" <EOL> if code == signal . SIGABRT : <EOL> return "<STR_LIT>" <EOL> if code == signal . SIGTRAP and sys . platform == "<STR_LIT>" : <EOL> return "<STR_LIT>" <EOL> return "<STR_LIT>" % code <EOL> class CommandFailedException ( qisys . error . Error ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , cmd , returncode , cwd = None , stdout = None , stderr = None ) : <EOL> self . cmd = cmd <EOL> self . cwd = cwd <EOL> if cwd is None : <EOL> self . cwd = os . getcwd ( ) <EOL> self . returncode = returncode <EOL> self . stdout = stdout <EOL> if stdout is None : <EOL> self . stdout = "<STR_LIT>" <EOL> self . stderr = stderr <EOL> if stderr is None : <EOL> self . stderr = "<STR_LIT>" <EOL> def __str__ ( self ) : <EOL> mess = """<STR_LIT>""" <EOL> mess = mess . format ( cmd = self . cmd , returncode = self . returncode , <EOL> cwd = self . cwd ) <EOL> if self . stdout : <EOL> mess += "<STR_LIT>" <EOL> mess = "<STR_LIT:\n>" . join ( "<STR_LIT:U+0020>" + line for line in self . stdout . split ( "<STR_LIT:\n>" ) ) <EOL> if self . stderr : <EOL> mess += "<STR_LIT>" <EOL> mess = "<STR_LIT:\n>" . join ( "<STR_LIT:U+0020>" + line for line in self . stderr . split ( "<STR_LIT:\n>" ) ) <EOL> return mess <EOL> class ProcessCrashedError ( qisys . error . Error ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , cmd ) : <EOL> self . cmd = cmd <EOL> def __str__ ( self ) : <EOL> mess = "<STR_LIT>" % os . path . basename ( self . cmd [ <NUM_LIT:0> ] ) <EOL> mess += "<STR_LIT>" % self . cmd <EOL> return mess <EOL> class NotInPath ( qisys . error . Error ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , executable , env = None ) : <EOL> self . executable = executable <EOL> self . env = env <EOL> def __str__ ( self ) : <EOL> if self . env : <EOL> path_env = self . env . get ( "<STR_LIT>" ) <EOL> else : <EOL> path_env = os . environ [ "<STR_LIT>" ] <EOL> mess = "<STR_LIT>" % self . executable <EOL> mess += "<STR_LIT>" <EOL> mess += "<STR_LIT:\n>" . join ( path_env . split ( os . pathsep ) ) <EOL> return mess <EOL> def find_program ( executable , env = None , raises = False ) : <EOL> """<STR_LIT>""" <EOL> import qibuild . config <EOL> if executable in _FIND_PROGRAM_CACHE : <EOL> return _FIND_PROGRAM_CACHE [ executable ] <EOL> full_path = None <EOL> res = None <EOL> if not env : <EOL> env = qibuild . config . get_build_env ( ) <EOL> if not env : <EOL> env = os . environ <EOL> env_path = env . get ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> for path in env_path . split ( os . pathsep ) : <EOL> res = _find_program_in_path ( executable , path ) <EOL> if res : <EOL> break <EOL> if res : <EOL> _FIND_PROGRAM_CACHE [ executable ] = res <EOL> return res <EOL> else : <EOL> if raises : <EOL> raise NotInPath ( executable , env = env ) <EOL> return None <EOL> def _find_program_in_path_win ( executable , path ) : <EOL> path_ext = os . environ [ "<STR_LIT>" ] <EOL> extensions = path_ext . split ( "<STR_LIT:;>" ) <EOL> extensions = [ x . lower ( ) for x in extensions ] <EOL> extensions . append ( "<STR_LIT>" ) <EOL> for ext in extensions : <EOL> candidate = executable + ext <EOL> res = _check_access ( candidate , path ) <EOL> if res : <EOL> return res <EOL> def _find_program_in_path ( executable , path ) : <EOL> if os . name == '<STR_LIT>' : <EOL> return _find_program_in_path_win ( executable , path ) <EOL> else : <EOL> return _check_access ( executable , path ) <EOL> def _check_access ( executable , path ) : <EOL> full_path = os . path . join ( path , executable ) <EOL> if os . path . isfile ( full_path ) and os . access ( full_path , os . X_OK ) : <EOL> return full_path <EOL> def check_output ( * popenargs , ** kwargs ) : <EOL> r"""<STR_LIT>""" <EOL> ui . debug ( "<STR_LIT>" , * popenargs ) <EOL> cwd = kwargs . get ( '<STR_LIT>' ) <EOL> if sys . version_info <= ( <NUM_LIT:2> , <NUM_LIT:7> ) : <EOL> if '<STR_LIT>' in kwargs : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> process = subprocess . Popen ( stdout = subprocess . PIPE , * popenargs , ** kwargs ) <EOL> output , error = process . communicate ( ) <EOL> retcode = process . poll ( ) <EOL> if retcode : <EOL> cmd = kwargs . get ( "<STR_LIT:args>" ) <EOL> if cmd is None : <EOL> cmd = popenargs [ <NUM_LIT:0> ] <EOL> raise CommandFailedException ( cmd , retcode , cwd = cwd , <EOL> stdout = output , stderr = error ) <EOL> else : <EOL> try : <EOL> output = subprocess . check_output ( * popenargs , ** kwargs ) <EOL> except subprocess . CalledProcessError as err : <EOL> raise CommandFailedException ( err . cmd , err . returncode , <EOL> cwd = cwd , stdout = err . output ) <EOL> ui . debug ( output ) <EOL> return output <EOL> def check_output_error ( * popenargs , ** kwargs ) : <EOL> r"""<STR_LIT>""" <EOL> if '<STR_LIT>' in kwargs : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if '<STR_LIT>' in kwargs : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> process = subprocess . Popen ( stdout = subprocess . PIPE , stderr = subprocess . PIPE , * popenargs , ** kwargs ) <EOL> output , error = process . communicate ( ) <EOL> retcode = process . poll ( ) <EOL> if retcode : <EOL> cmd = kwargs . get ( "<STR_LIT:args>" ) <EOL> if cmd is None : <EOL> cmd = popenargs [ <NUM_LIT:0> ] <EOL> raise CommandFailedException ( cmd , retcode , stdout = output , stderr = error ) <EOL> return ( output , error ) <EOL> def check_is_in_path ( executable , env = None ) : <EOL> """<STR_LIT>""" <EOL> if find_program ( executable , env = env ) is None : <EOL> raise NotInPath ( executable , env = env ) <EOL> def call ( cmd , cwd = None , env = None , ignore_ret_code = False , quiet = False ) : <EOL> """<STR_LIT>""" <EOL> executable = cmd [ <NUM_LIT:0> ] <EOL> if os . path . isabs ( executable ) : <EOL> exe_full_path = executable <EOL> else : <EOL> exe_full_path = find_program ( cmd [ <NUM_LIT:0> ] , env = env ) <EOL> if not exe_full_path : <EOL> raise NotInPath ( cmd [ <NUM_LIT:0> ] , env = env ) <EOL> cmd [ <NUM_LIT:0> ] = exe_full_path <EOL> if cwd : <EOL> if not os . path . exists ( cwd ) : <EOL> raise qisys . error . Error ( "<STR_LIT>" % <EOL> ( "<STR_LIT:U+0020>" . join ( cmd ) , cwd ) ) <EOL> ui . debug ( "<STR_LIT>" , "<STR_LIT:U+0020>" . join ( cmd ) ) <EOL> call_kwargs = { "<STR_LIT>" : env , "<STR_LIT>" : cwd } <EOL> if quiet or ui . CONFIG . get ( "<STR_LIT>" ) : <EOL> call_kwargs [ "<STR_LIT>" ] = subprocess . PIPE <EOL> returncode = subprocess . call ( cmd , ** call_kwargs ) <EOL> if returncode != <NUM_LIT:0> and not ignore_ret_code : <EOL> raise CommandFailedException ( cmd , returncode , cwd ) <EOL> return returncode <EOL> @ contextlib . contextmanager <EOL> def call_background ( cmd , cwd = None , env = None ) : <EOL> """<STR_LIT>""" <EOL> process = subprocess . Popen ( cmd , cwd = cwd , env = env ) <EOL> caught_error = None <EOL> try : <EOL> yield <EOL> except Exception , err : <EOL> caught_error = err <EOL> finally : <EOL> try : <EOL> if process . poll ( ) != None : <EOL> raise ProcessCrashedError ( cmd ) <EOL> else : <EOL> process . kill ( ) <EOL> except ProcessCrashedError , err : <EOL> caught_error = err <EOL> if caught_error : <EOL> raise caught_error </s>
