Bug #278895 - After EbuildIpcDaemon identifies an ebuild process that
authorZac Medico <zmedico@gentoo.org>
Fri, 13 Aug 2010 14:47:56 +0000 (07:47 -0700)
committerZac Medico <zmedico@gentoo.org>
Fri, 13 Aug 2010 14:47:56 +0000 (07:47 -0700)
has left an orphan child process running in the background, generate
an eerror message about a 'zombie' process and note the pid.

pym/_emerge/AbstractEbuildProcess.py
pym/_emerge/SubProcess.py

index 913a32d12a139d2fac2b41398a8c79f04e3c7536..c3f539dcdca26ba50c25bff6fa4b263a4b28e308 100644 (file)
@@ -60,6 +60,16 @@ class AbstractEbuildProcess(SpawnProcess):
                                # being killed by a signal.
                                self.cancel()
 
+       def _zombie(self):
+               phase = self._get_phase()
+
+               msg = _("The ebuild phase '%s' appears "
+               "to have left a zombie process with "
+               "pid %d.") % (phase, self.pid)
+
+               for l in textwrap.wrap(msg, 72):
+                       eerror(l, phase=phase, key=self.settings.mycpv)
+
        def _pipe(self, fd_pipes):
                stdout_pipe = fd_pipes.get(1)
                got_pty, master_fd, slave_fd = \
index b1b5201eb910e944a7a9f181fe34e407e616393d..b6489c3932a2febeb674ff8e59079dc1b4c6739e 100644 (file)
@@ -61,7 +61,21 @@ class SubProcess(AbstractPollTask):
                        return self.returncode
 
                if self._registered:
-                       self.scheduler.schedule(self._reg_id)
+                       if self.cancelled:
+                               timeout = 1000
+                               self.scheduler.schedule(self._reg_id, timeout=timeout)
+                               if self._registered:
+                                       try:
+                                               os.kill(self.pid, signal.SIGKILL)
+                                       except OSError as e:
+                                               if e.errno != errno.ESRCH:
+                                                       raise
+                                               del e
+                                       self.scheduler.schedule(self._reg_id, timeout=timeout)
+                                       if self._registered:
+                                               self._zombie()
+                       else:
+                               self.scheduler.schedule(self._reg_id)
                        self._unregister()
                        if self.returncode is not None:
                                return self.returncode
@@ -78,6 +92,9 @@ class SubProcess(AbstractPollTask):
 
                return self.returncode
 
+       def _zombie(self):
+               pass
+
        def _unregister(self):
                """
                Unregister from the scheduler and close open files.