summaryrefslogtreecommitdiff
path: root/debian/scripts/timeout-inactive.py
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2019-12-02 13:09:17 +0300
committerIgor Pashev <pashev.igor@gmail.com>2019-12-02 13:09:17 +0300
commit38fde63f74091af1f6a0d485474769bb6b4f17ce (patch)
tree1317a1fa2ef61c710ff5c653f43c0af8bb164ca6 /debian/scripts/timeout-inactive.py
downloadpypy-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-xdebian/scripts/timeout-inactive.py84
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()