hgbook
changeset 79:53427f786a0f
Make run-example time out if shell seems to get stuck.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Mon Sep 04 14:31:17 2006 -0700 (2006-09-04) |
parents | a893de25bc24 |
children | ea951cfb5cd9 |
files | en/examples/run-example |
line diff
1.1 --- a/en/examples/run-example Mon Sep 04 14:20:05 2006 -0700 1.2 +++ b/en/examples/run-example Mon Sep 04 14:31:17 2006 -0700 1.3 @@ -10,6 +10,7 @@ 1.4 import os 1.5 import pty 1.6 import re 1.7 +import select 1.8 import shutil 1.9 import signal 1.10 import stat 1.11 @@ -41,9 +42,12 @@ 1.12 prompt = '__run_example_prompt__ ' 1.13 pi_re = re.compile(r'#\$\s*(name):\s*(.*)$') 1.14 1.15 + timeout = 5 1.16 + 1.17 def __init__(self, name, verbose): 1.18 self.name = name 1.19 self.verbose = verbose 1.20 + self.poll = select.poll() 1.21 1.22 def parse(self): 1.23 '''yield each hunk of input from the file.''' 1.24 @@ -76,13 +80,23 @@ 1.25 else: 1.26 return rs 1.27 1.28 + timeout = 5 1.29 + 1.30 + def read(self): 1.31 + events = self.poll.poll(self.timeout * 1000) 1.32 + if not events: 1.33 + print >> sys.stderr, '[timed out after %d seconds]' % self.timeout 1.34 + os.kill(self.pid, signal.SIGHUP) 1.35 + return '' 1.36 + return os.read(self.cfd, 1024) 1.37 + 1.38 def receive(self): 1.39 out = cStringIO.StringIO() 1.40 while True: 1.41 try: 1.42 if self.verbose: 1.43 sys.stderr.write('< ') 1.44 - s = os.read(self.cfd, 1024) 1.45 + s = self.read() 1.46 except OSError, err: 1.47 if err.errno == errno.EIO: 1.48 return '' 1.49 @@ -126,8 +140,8 @@ 1.50 rcfp.close() 1.51 sys.stdout.flush() 1.52 sys.stderr.flush() 1.53 - pid, self.cfd = pty.fork() 1.54 - if pid == 0: 1.55 + self.pid, self.cfd = pty.fork() 1.56 + if self.pid == 0: 1.57 cmdline = ['/usr/bin/env', 'bash', '--noediting', '--noprofile', 1.58 '--norc'] 1.59 try: 1.60 @@ -136,10 +150,12 @@ 1.61 print >> sys.stderr, '%s: %s' % (cmdline[0], err.strerror) 1.62 sys.stderr.flush() 1.63 os._exit(0) 1.64 + self.poll.register(self.cfd, select.POLLIN | select.POLLERR | 1.65 + select.POLLHUP) 1.66 try: 1.67 try: 1.68 # eat first prompt string from shell 1.69 - os.read(self.cfd, 1024) 1.70 + self.read() 1.71 # setup env and prompt 1.72 self.sendreceive('source %s\n' % rcfile) 1.73 for hunk in self.parse(): 1.74 @@ -173,7 +189,7 @@ 1.75 open(self.name + '.run', 'w') 1.76 except: 1.77 print >> sys.stderr, '(killed)' 1.78 - os.kill(pid, signal.SIGKILL) 1.79 + os.kill(self.pid, signal.SIGKILL) 1.80 pid, rc = os.wait() 1.81 raise 1.82 else: 1.83 @@ -184,7 +200,7 @@ 1.84 os.close(self.cfd) 1.85 except IOError: 1.86 pass 1.87 - os.kill(pid, signal.SIGTERM) 1.88 + os.kill(self.pid, signal.SIGTERM) 1.89 pid, rc = os.wait() 1.90 if rc: 1.91 if os.WIFEXITED(rc):