Mercurial > hgbook
changeset 79:53427f786a0f
Make run-example time out if shell seems to get stuck.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Mon, 04 Sep 2006 14:31:17 -0700 |
parents | a893de25bc24 |
children | ea951cfb5cd9 |
files | en/examples/run-example |
diffstat | 1 files changed, 22 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/en/examples/run-example Mon Sep 04 14:20:05 2006 -0700 +++ b/en/examples/run-example Mon Sep 04 14:31:17 2006 -0700 @@ -10,6 +10,7 @@ import os import pty import re +import select import shutil import signal import stat @@ -41,9 +42,12 @@ prompt = '__run_example_prompt__ ' pi_re = re.compile(r'#\$\s*(name):\s*(.*)$') + timeout = 5 + def __init__(self, name, verbose): self.name = name self.verbose = verbose + self.poll = select.poll() def parse(self): '''yield each hunk of input from the file.''' @@ -76,13 +80,23 @@ else: return rs + timeout = 5 + + def read(self): + events = self.poll.poll(self.timeout * 1000) + if not events: + print >> sys.stderr, '[timed out after %d seconds]' % self.timeout + os.kill(self.pid, signal.SIGHUP) + return '' + return os.read(self.cfd, 1024) + def receive(self): out = cStringIO.StringIO() while True: try: if self.verbose: sys.stderr.write('< ') - s = os.read(self.cfd, 1024) + s = self.read() except OSError, err: if err.errno == errno.EIO: return '' @@ -126,8 +140,8 @@ rcfp.close() sys.stdout.flush() sys.stderr.flush() - pid, self.cfd = pty.fork() - if pid == 0: + self.pid, self.cfd = pty.fork() + if self.pid == 0: cmdline = ['/usr/bin/env', 'bash', '--noediting', '--noprofile', '--norc'] try: @@ -136,10 +150,12 @@ print >> sys.stderr, '%s: %s' % (cmdline[0], err.strerror) sys.stderr.flush() os._exit(0) + self.poll.register(self.cfd, select.POLLIN | select.POLLERR | + select.POLLHUP) try: try: # eat first prompt string from shell - os.read(self.cfd, 1024) + self.read() # setup env and prompt self.sendreceive('source %s\n' % rcfile) for hunk in self.parse(): @@ -173,7 +189,7 @@ open(self.name + '.run', 'w') except: print >> sys.stderr, '(killed)' - os.kill(pid, signal.SIGKILL) + os.kill(self.pid, signal.SIGKILL) pid, rc = os.wait() raise else: @@ -184,7 +200,7 @@ os.close(self.cfd) except IOError: pass - os.kill(pid, signal.SIGTERM) + os.kill(self.pid, signal.SIGTERM) pid, rc = os.wait() if rc: if os.WIFEXITED(rc):