diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2019-12-02 13:09:17 +0300 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2019-12-02 13:09:17 +0300 |
commit | 38fde63f74091af1f6a0d485474769bb6b4f17ce (patch) | |
tree | 1317a1fa2ef61c710ff5c653f43c0af8bb164ca6 /debian/scripts/timeout-inactive.py | |
download | pypy-debian.tar.gz |
Import pypy (7.2.0+dfsg-1)debian/7.2.0+dfsg-1debian
Diffstat (limited to 'debian/scripts/timeout-inactive.py')
-rwxr-xr-x | debian/scripts/timeout-inactive.py | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/debian/scripts/timeout-inactive.py b/debian/scripts/timeout-inactive.py new file mode 100755 index 0000000..d865fc8 --- /dev/null +++ b/debian/scripts/timeout-inactive.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python + +import argparse +import re +import signal +import subprocess +import sys +import threading + + +def main(): + p = argparse.ArgumentParser( + description='Run a program, and kill it if it is silent for too long.' + 'After the arguments, specify the program to run prefixed ' + 'with -- .') + p.add_argument('--timeout', type=parse_timeout, + help='Timeout (in seconds, if no unit specified') + + our_args = sys.argv[1:] + cmd = [] + if '--' in our_args: + index = our_args.index('--') + cmd = our_args[index + 1:] + our_args = our_args[:index] + + args = p.parse_args(our_args) + if not cmd: + p.error('No command specified') + + run_cmd(cmd, args.timeout) + + +def parse_timeout(arg): + m = re.match(r'(\d+) *(s(ec(ond)?s?)?|m(in(ute)?s?)?|h((ou)?rs?)?)?', arg) + if not m: + raise argparse.ArgumentTypeError('Un-parseable time') + value = int(m.group(1)) + unit = m.group(2) + if unit: + unit = unit[0] + if unit == 'm': + return value * 60 + if unit == 'h': + return value * 60 * 60 + return value + + +def run_cmd(cmd, timeout): + p = subprocess.Popen(cmd, bufsize=1, stdout=subprocess.PIPE) + watchdog = Watchdog(timeout, p) + watchdog.start() + while True: + line = p.stdout.readline() + watchdog.event.set() + sys.stdout.write(line) + sys.stdout.flush() + if p.poll() != None: + sys.exit(p.returncode) + + +class Watchdog(threading.Thread): + def __init__(self, timeout, process): + super(Watchdog, self).__init__() + self.daemon = True + self.timeout = timeout + self.process = process + self.event = threading.Event() + + def run(self): + while True: + ev = self.event.wait(self.timeout) + if ev is True: + self.event.clear() + else: + sys.stderr.write( + '\nTimed out after {} seconds of inactivity...\n' + .format(self.timeout)) + sys.stderr.flush() + self.process.send_signal(signal.SIGINT) + return + + +if __name__ == '__main__': + main() |