Ejemplo n.º 1
0
 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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
        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)
Ejemplo n.º 5
0
    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)