def _kill_process(pid): """ Callback method to kill a process. """ p = Popen(['ps', '--ppid', str(pid)], stdout=PIPE, creationflags=PROC_CREATIONFLAGS) child_pids = [] for line in p.stdout: if len(line.split()) > 0: local_pid = (line.split())[0] if local_pid.isdigit(): child_pids.append(int(local_pid)) try: # Windows does not have SIGKILL, so use SIGTERM instead sig = getattr(signal, 'SIGKILL', signal.SIGTERM) os.kill(pid, sig) for child_pid in child_pids: try: os.kill(child_pid, sig) except OSError: pass kill_check.set( ) # tell the main routine that the process was killed except OSError: # It is possible that the process gets completed in the duration after timeout # happens and before we try to kill the process. pass return
def __unpack_args(cls, arg_list): if not isinstance(arg_list, (list, tuple)): # This is just required for unicode conversion, as subprocess can't handle it # However, in any other case, passing strings (usually utf-8 encoded) is totally fine if not PY3 and isinstance(arg_list, str): return [arg_list.encode(defenc)] return [str(arg_list)] outlist = list() for arg in arg_list: if isinstance(arg_list, (list, tuple)): outlist.extend(cls.__unpack_args(arg)) elif not PY3 and isinstance(arg_list, str): outlist.append(arg_list.encode(defenc)) # END recursion else: outlist.append(str(arg)) # END for each arg return outlist
def _prepare_ref(self, ref): # required for command to separate refs on stdin, as bytes refstr = ref if isinstance(ref, bytes): # Assume 40 bytes hexsha - bin-to-ascii for some reason returns bytes, not text refstr = ref.decode('ascii') elif not isinstance(ref, string_types): refstr = str(ref) # could be ref-object if not refstr.endswith("\n"): refstr += "\n" return refstr.encode(defenc)
def __del__(self): if self.proc is None: return proc = self.proc self.proc = None if proc.stdin: proc.stdin.close() if proc.stdout: proc.stdout.close() if proc.stderr: proc.stderr.close() # did the process finish already so we have a return code ? if proc.poll() is not None: return # can be that nothing really exists anymore ... if os is None or getattr(os, 'kill', None) is None: return # try to kill it try: proc.terminate() proc.wait() # ensure process goes away except OSError as ex: log.info("Ignored error after process had died: %r", ex) pass # ignore error when process already died except AttributeError: # try windows # for some reason, providing None for stdout/stderr still prints something. This is why # we simply use the shell and redirect to nul. Its slower than CreateProcess, question # is whether we really want to see all these messages. Its annoying no matter what. if is_win: call( ("TASKKILL /F /T /PID %s 2>nul 1>nul" % str(proc.pid)), shell=True)
def _call_process(self, method, *args, **kwargs): """Run the given git command with the specified arguments and return the result as a String :param method: is the command. Contained "_" characters will be converted to dashes, such as in 'ls_files' to call 'ls-files'. :param args: is the list of arguments. If None is included, it will be pruned. This allows your commands to call git more conveniently as None is realized as non-existent :param kwargs: It contains key-values for the following: - the :meth:`execute()` kwds, as listed in :var:`execute_kwargs`; - "command options" to be converted by :meth:`transform_kwargs()`; - the `'insert_kwargs_after'` key which its value must match one of ``*args``, and any cmd-options will be appended after the matched arg. Examples:: git.rev_list('master', max_count=10, header=True) turns into:: git rev-list max-count 10 --header master :return: Same as ``execute``""" # Handle optional arguments prior to calling transform_kwargs # otherwise these'll end up in args, which is bad. exec_kwargs = dict( (k, v) for k, v in list(kwargs.items()) if k in execute_kwargs) opts_kwargs = dict( (k, v) for k, v in list(kwargs.items()) if k not in execute_kwargs) insert_after_this_arg = opts_kwargs.pop('insert_kwargs_after', None) # Prepare the argument list opt_args = self.transform_kwargs(**opts_kwargs) ext_args = self.__unpack_args([a for a in args if a is not None]) if insert_after_this_arg is None: args = opt_args + ext_args else: try: index = ext_args.index(insert_after_this_arg) except ValueError: raise ValueError( "Couldn't find argument '%s' in args %s to insert cmd options after" % (insert_after_this_arg, str(ext_args))) # end handle error args = ext_args[:index + 1] + opt_args + ext_args[index + 1:] # end handle opts_kwargs call = [self.GIT_PYTHON_GIT_EXECUTABLE] # add persistent git options call.extend(self._persistent_git_options) # add the git options, then reset to empty # to avoid side_effects call.extend(self._git_options) self._git_options = () call.append(dashify(method)) call.extend(args) return self.execute(call, **exec_kwargs)