From: Zac Medico Date: Thu, 1 Mar 2007 20:37:15 +0000 (-0000) Subject: Use an alarm signal to implement a timeout when rsync is fetching the server timestam... X-Git-Tag: v2.2_pre1~1636 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=5cb9305ebe767b4cfa09f85999c25377a00f9ef3;p=portage.git Use an alarm signal to implement a timeout when rsync is fetching the server timestamp file, since rsync's --timeout option doesn't apply to the initial connection attempt. svn path=/main/trunk/; revision=6109 --- diff --git a/pym/emerge/__init__.py b/pym/emerge/__init__.py index e91f6b1a7..1486f4c5e 100644 --- a/pym/emerge/__init__.py +++ b/pym/emerge/__init__.py @@ -3989,23 +3989,51 @@ def action_sync(settings, trees, mtimedb, myopts, myaction): mycommand.append(dosyncuri.rstrip("/") + \ "/metadata/timestamp.chk") mycommand.append(tmpservertimestampfile) + content = None + mypids = [] try: - exitcode = portage.process.spawn( - mycommand, env=settings.environ()) - content = portage.grabfile(tmpservertimestampfile) - if content: + def timeout_handler(signum, frame): + raise portage.exception.PortageException("timed out") + signal.signal(signal.SIGALRM, timeout_handler) + # Timeout here in case the server is unresponsive. The + # --timeout rsync option doesn't apply to the initial + # connection attempt. + signal.alarm(15) + try: + mypids.extend(portage.process.spawn( + mycommand, env=settings.environ(), returnpid=True)) + exitcode = os.waitpid(mypids[0], 0)[1] + content = portage.grabfile(tmpservertimestampfile) + finally: + signal.alarm(0) try: - servertimestamp = time.mktime(time.strptime( - content[0], "%a, %d %b %Y %H:%M:%S +0000")) - except OverflowError, ValueError: + os.unlink(tmpservertimestampfile) + except OSError: pass - del content - finally: + except portage.exception.PortageException, e: + # timed out + print e + del e + if mypids and os.waitpid(mypids[0], os.WNOHANG) == (0,0): + os.kill(mypids[0], signal.SIGTERM) + os.waitpid(mypids[0], 0) + # This is the same code rsync uses for timeout. + exitcode = 30 + else: + if mypids: + portage.process.spawned_pids.remove(mypids[0]) + if exitcode != os.EX_OK: + if exitcode & 0xff: + exitcode = (exitcode & 0xff) << 8 + else: + exitcode >> 8 + if content: try: - os.unlink(tmpservertimestampfile) - except OSError: + servertimestamp = time.mktime(time.strptime( + content[0], "%a, %d %b %Y %H:%M:%S +0000")) + except OverflowError, ValueError: pass - del mycommand + del mycommand, mypids, content if exitcode == os.EX_OK: if (servertimestamp != 0) and (servertimestamp == mytimestamp): emergelog(xterm_titles,