summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-07-10 01:24:43 +0000
committerZac Medico <zmedico@gentoo.org>2008-07-10 01:24:43 +0000
commitdcf36ddfe69c9a2dd65fc80731623d719fe49954 (patch)
tree40fa4cbc1de797f0de4f90bae354b3f7c13b7241
parent04300e38591d18b50f49853ddcd164bc801f183b (diff)
downloadportage-dcf36ddfe69c9a2dd65fc80731623d719fe49954.tar.gz
portage-dcf36ddfe69c9a2dd65fc80731623d719fe49954.tar.bz2
portage-dcf36ddfe69c9a2dd65fc80731623d719fe49954.zip
* Handle errno.ECHILD and errno.ESRCH from waitpid() and kill() calls. These
errors commonly occur when ^C is used to kill emerge. * Remove spawned pids from portage.process.spawned_pids immediately in order to avoid a race condition for removing it. svn path=/main/trunk/; revision=11007
-rw-r--r--pym/_emerge/__init__.py32
1 files changed, 28 insertions, 4 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index 73ce61c61..a1a3d6fe7 100644
--- a/pym/_emerge/__init__.py
+++ b/pym/_emerge/__init__.py
@@ -1712,7 +1712,15 @@ class SubProcess(AsynchronousTask):
return self.returncode
if self.pid is None:
return self.returncode
- retval = os.waitpid(self.pid, os.WNOHANG)
+
+ try:
+ retval = os.waitpid(self.pid, os.WNOHANG)
+ except OSError, e:
+ if e.errno != errno.ECHILD:
+ raise
+ del e
+ retval = (self.pid, 1)
+
if retval == (0, 0):
return None
self._set_returncode(retval)
@@ -1720,7 +1728,13 @@ class SubProcess(AsynchronousTask):
def cancel(self):
if self.isAlive():
- os.kill(self.pid, signal.SIGTERM)
+ try:
+ os.kill(self.pid, signal.SIGTERM)
+ except OSError, e:
+ if e.errno != errno.ESRCH:
+ raise
+ del e
+
self.cancelled = True
if self.pid is not None:
self.wait()
@@ -1735,13 +1749,21 @@ class SubProcess(AsynchronousTask):
return self.returncode
if self.registered:
self.scheduler.schedule(self._reg_id)
- self._set_returncode(os.waitpid(self.pid, 0))
+ try:
+ wait_retval = os.waitpid(self.pid, 0)
+ except OSError, e:
+ if e.errno != errno.ECHILD:
+ raise
+ del e
+ self._set_returncode((self.pid, 1))
+ else:
+ self._set_returncode(wait_retval)
return self.returncode
def _set_returncode(self, wait_retval):
retval = wait_retval[1]
- portage.process.spawned_pids.remove(self.pid)
+
if retval != os.EX_OK:
if retval & 0xff:
retval = (retval & 0xff) << 8
@@ -1833,6 +1855,7 @@ class SpawnProcess(SubProcess):
retval = portage.process.spawn(self.args, **kwargs)
self.pid = retval[0]
+ portage.process.spawned_pids.remove(self.pid)
os.close(slave_fd)
files.process = os.fdopen(master_fd, 'r')
@@ -2358,6 +2381,7 @@ class EbuildPhase(SubProcess):
fd_pipes=fd_pipes, returnpid=True)
self.pid = retval[0]
+ portage.process.spawned_pids.remove(self.pid)
if logfile:
files.log = open(logfile, 'a')