runtest.py: cleanup all grandchildren too.
authorJoel Martin <github@martintribe.org>
Mon, 2 Mar 2015 23:36:09 +0000 (17:36 -0600)
committerJoel Martin <github@martintribe.org>
Mon, 2 Mar 2015 23:36:09 +0000 (17:36 -0600)
Launch Popen with process group and kill that instead. Use atexit to
register cleanup function rather than direct calls.

docs/TODO
runtest.py

index e586f52..68c5393 100644 (file)
--- a/docs/TODO
+++ b/docs/TODO
@@ -5,12 +5,12 @@ All:
     - test to make sure slurp captures final newline
     - make sure errors propagate/print properly when self-hosted
 
-    - change perf test to run for 10 seconds and then calculate number
+    * change perf test to run for 10 seconds and then calculate number
       of iterations per second
     - redefine (defmacro!) as (def! (macro*))
     - runtest expect fixes:
         * stop using expect, so we can drop --raw option
-        - fix C#, VB
+        * fix C#, VB
         - fix long line splitting in runtest
     - regular expression matching in runtest
     - add re (use in rep) everywhere and use that (to avoid printing)
@@ -85,7 +85,7 @@ Java:
     - MAL formatting is a bit off with mal/clojurewest2014.mal
 
 Javascript:
-    - interop: callbacks using Mal functions
+    - interop: adopt techniques from miniMAL
     - fix "user> " prompt with mal/clojurewest2014.mal
 
 Lua:
index e1db90a..a7f0e44 100755 (executable)
@@ -3,7 +3,7 @@
 import os, sys, re
 import argparse, time
 
-import pty
+import pty, signal, atexit
 from subprocess import Popen, STDOUT, PIPE
 from select import select
 
@@ -33,16 +33,24 @@ parser.add_argument('mal_cmd', nargs="*",
 
 class Runner():
     def __init__(self, args, mono=False):
+        #print "args: %s" % repr(args)
         self.mono = mono
-        print "args: %s" % repr(args)
+
+        # Cleanup child process on exit
+        atexit.register(self.cleanup)
+
         if mono:
-            self.p = Popen(args, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
+            self.p = Popen(args, bufsize=0,
+                           stdin=PIPE, stdout=PIPE, stderr=STDOUT,
+                           preexec_fn=os.setsid)
             self.stdin = self.p.stdin
             self.stdout = self.p.stdout
         else:
             # provide tty to get 'interactive' readline to work
             master, slave = pty.openpty()
-            self.p = Popen(args, bufsize=0, stdin=slave, stdout=slave, stderr=STDOUT)
+            self.p = Popen(args, bufsize=0,
+                           stdin=slave, stdout=slave, stderr=STDOUT,
+                           preexec_fn=os.setsid)
             self.stdin = os.fdopen(master, 'r+b', 0)
             self.stdout = self.stdin
 
@@ -79,8 +87,9 @@ class Runner():
             self.buf += str + "\r\n"
 
     def cleanup(self):
+        #print "cleaning up"
         if self.p:
-            self.p.kill()
+            os.killpg(self.p.pid, signal.SIGTERM)
             self.p = None
 
 
@@ -139,7 +148,6 @@ def assert_prompt(timeout):
     else:
         print "Did not get 'user> ' or 'mal-user> ' prompt"
         print "    Got      : %s" % repr(r.buf)
-        r.cleanup()
         sys.exit(1)
 
 
@@ -177,9 +185,7 @@ while test_data:
             fail_cnt += 1
     except:
         print "Got Exception"
-        r.cleanup()
         sys.exit(1)
-r.cleanup()
 
 if fail_cnt > 0:
     print "FAILURES: %d" % fail_cnt