Esempio n. 1
0
    def exited(self, status):
        # Log last output
        for line in self.readlines():
            pass

        # Display exit code
        if status is not None:
            log_func = self.warning
            info = []
            if WCOREDUMP(status):
                info.append("core.%s dumped!" % self._pid)
                log_func = self.error
            if WIFSIGNALED(status):
                signal = WTERMSIG(status)
                signal = SIGNAME.get(signal, signal)
                info.append("signal %s" % signal)
            if WIFEXITED(status):
                info.append("exitcode=%s" % WEXITSTATUS(status))
            if info:
                log_func("Exit (%s)" % ", ".join(info))
            else:
                log_func("Exit")
        else:
            self.error("Process exited (ECHILD error)")

        # Delete process
        self.process = None
        self._pid = None
Esempio n. 2
0
def wait_and_reap_zombies(pid):
    _, status = waitpid(pid, 0)
    try:
        while True:
            waitpid(-1, WNOHANG)
    except ChildProcessError:
        pass
    if WIFSIGNALED(status):
        return -WTERMSIG(status)
    return WEXITSTATUS(status)
Esempio n. 3
0
 def execute(self, *args):
     process = Popen4([self.facility.path] + self.facility.args +
                      list(args))
     timers = [
         Timer(time, self.kill, [process.pid, signal])
         for time, signal in self.facility.wait.iteritems()
     ]
     for timer in timers:
         timer.start()
     status = process.wait()
     for timer in timers:
         # No penalty, btw, for cancelling a dead timer
         if timer.isAlive():
             timer.cancel()
     process.tochild.close()
     if __debug__:
         while True:
             line = process.fromchild.readline()
             if line:
                 syslog(line)
             else:
                 break
     process.fromchild.close()
     command = basename(self.facility.path)
     if WIFEXITED(status):
         exit_status = WEXITSTATUS(status)
         if exit_status != EX_OK:
             raise ExecutionError(
                 EX_SOFTWARE, '`%(command)s\' exited with \
             error-code %(exit_status)d' % {
                     'command': command,
                     'exit_status': exit_status
                 })
     elif WIFSIGNALED(status):
         raise ExecutionError(
             EX_SOFTWARE, '`%(command)s\' terminated \
         with signal %(signal)d' % {
                 'command': command,
                 'signal': WTERMSIG(status)
             })
     elif WIFSTOPPED(status):
         raise ExecutionError(
             EX_SOFTWARE, '`%(command)s\' stopped with \
         signal %(signal)d' % {
                 'command': command,
                 'signal': WSTOPSIG(status)
             })
     else:
         # Failsafe: timers should have killed the process by this point, or
         # it should have ended naturally.
         kill(process.pid, SIGKILL)
         raise ExecutionError(
             EX_SOFTWARE, 'Failed timer on `%(command)s\'; \
         terminating the process extraordinarily.' % {'command': command})
def formatProcessStatus(status, title="Process"):
    if WIFSTOPPED(status):
        signum = WSTOPSIG(status)
        return "%s stopped by signal %s" % (title, signalName(signum))

    if WIFSIGNALED(status):
        signum = WTERMSIG(status)
        return "%s killed by signal %s" % (title, signalName(signum))

    if not WIFEXITED(status):
        raise ValueError("Invalid status: %r" % status)

    exitcode = WEXITSTATUS(status)
    if exitcode:
        return "%s exited with code %s" % (title, exitcode)
    else:
        return "%s exited normally" % title
Esempio n. 5
0
def _waitpid(pid):
    """Convenience wrapper around the original waitpid invocation."""
    # 0 and -1 trigger a different behavior in waitpid. We disallow those
    # values.
    assert pid > 0

    while True:
        pid_, status = waitpid_(pid, 0)
        assert pid_ == pid

        if WIFEXITED(status):
            return WEXITSTATUS(status)
        elif WIFSIGNALED(status):
            # Signals are usually represented as the negated signal number.
            return -WTERMSIG(status)
        elif WIFSTOPPED(status) or WIFCONTINUED(status):
            # In our current usage scenarios we can simply ignore SIGSTOP and
            # SIGCONT by restarting the wait.
            continue
        else:
            assert False
            return 1
Esempio n. 6
0
def formatProcessStatus(status, title="Process"):
    """
    Format a process status (integer) as a string.
    """
    if WIFSTOPPED(status):
        signum = WSTOPSIG(status)
        text = "%s stopped by signal %s" % (title, signalName(signum))
    elif WIFSIGNALED(status):
        signum = WTERMSIG(status)
        text = "%s killed by signal %s" % (title, signalName(signum))
    else:
        if not WIFEXITED(status):
            raise ValueError("Invalid status: %r" % status)

        exitcode = WEXITSTATUS(status)
        if exitcode:
            text = "%s exited with code %s" % (title, exitcode)
        else:
            text = "%s exited normally" % title
    if WCOREDUMP(status):
        text += " (core dumped)"
    return text
Esempio n. 7
0
    def processStatus(self, status):
        # Process exited?
        if WIFEXITED(status):
            code = WEXITSTATUS(status)
            event = self.processExited(code)

        # Process killed by a signal?
        elif WIFSIGNALED(status):
            signum = WTERMSIG(status)
            event = self.processKilled(signum)

        # Invalid process status?
        elif not WIFSTOPPED(status):
            raise ProcessError(self, "Unknown process status: %r" % status)

        # Ptrace event?
        elif HAS_PTRACE_EVENTS and WPTRACEEVENT(status):
            event = WPTRACEEVENT(status)
            event = self.ptraceEvent(event)

        else:
            signum = WSTOPSIG(status)
            event = self.processSignal(signum)
        return event
Esempio n. 8
0
 def _event_handle_process_kill(self, status, pid):
     signum = WTERMSIG(status)
     logger.debug('process killed by a signal:%d, pid=%d' % (signum, pid))
     self.pid_dict.pop(pid)
     if len(self.pid_dict) == 0:
         self.process_exist = True