'UNIX implementation of process killing
@param errors: error messages. stop() will record messages into this list.
@type  errors: [str]'

def _stop_unix(self, errors):

    self.exit_code = self.popen.poll()
    if (self.exit_code is not None):
        self.popen = None
        self.stopped = True
        return
    pid = self.popen.pid
    pgid = os.getpgid(pid)
    try:
        os.killpg(pgid, signal.SIGINT)
        timeout_t = (time.time() + TIMEOUT_SIGINT)
        retcode = self.popen.poll()
        while ((time.time() < timeout_t) and (retcode is None)):
            time.sleep(0.1)
            retcode = self.popen.poll()
        if (retcode is None):
            printerrlog(('[%s]    escalating    to    SIGTERM' % self.name))
            timeout_t = (time.time() + TIMEOUT_SIGTERM)
            os.killpg(pgid, signal.SIGTERM)
            retcode = self.popen.poll()
            while ((time.time() < timeout_t) and (retcode is None)):
                time.sleep(0.2)
                retcode = self.popen.poll()
            if (retcode is None):
                printerrlog(('[%s]    escalating    to    SIGKILL' % self.name))
                errors.append(('process[%s,    pid    %s]:    required    SIGKILL.    May    still    be    running.' % (self.name, pid)))
                try:
                    os.killpg(pgid, signal.SIGKILL)
                except OSError as e:
                    if (e.args[0] == 3):
                        printerrlog(('no    [%s]    process    with    pid    [%s]' % (self.name, pid)))
                    else:
                        printerrlog(('errors    shutting    down    [%s]:    %s' % (self.name, e)))
    finally:
        self.popen = None
