Commit 82ce722d authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz
Browse files

* wrap/python/spot.py: Kill the shell and its children on timeout.

parent 64df4fbc
...@@ -27,6 +27,8 @@ if sys.hexversion < 0x03030000: ...@@ -27,6 +27,8 @@ if sys.hexversion < 0x03030000:
from spot_impl import * from spot_impl import *
import subprocess import subprocess
import os
import signal
from functools import lru_cache from functools import lru_cache
...@@ -360,16 +362,26 @@ def automata(*sources, timeout=None): ...@@ -360,16 +362,26 @@ def automata(*sources, timeout=None):
p = None p = None
proc = None proc = None
if filename[-1] == '|': if filename[-1] == '|':
# universal_newlines for str output instead of bytes
# when the pipe is read from Python (which happens
# when timeout is set).
proc = subprocess.Popen(filename[:-1], shell=True,
preexec_fn=os.setsid,
universal_newlines=True,
stdout=subprocess.PIPE)
if timeout is None: if timeout is None:
proc = subprocess.Popen(filename[:-1], shell=True,
stdout=subprocess.PIPE)
p = automaton_stream_parser(proc.stdout.fileno(), p = automaton_stream_parser(proc.stdout.fileno(),
filename, True) filename, True)
else: else:
# universal_newlines for str output instead of bytes try:
out = subprocess.check_output(filename[:-1], shell=True, out, err = proc.communicate(timeout=timeout)
universal_newlines=True, except subprocess.TimeoutExpired:
timeout=timeout) # Using subprocess.check_output() with timeout
# would just kill the shell, not its children.
os.killpg(proc.pid, signal.SIGKILL)
raise
finally:
proc = None
p = automaton_stream_parser(out, filename, True) p = automaton_stream_parser(out, filename, True)
elif '\n' in filename: elif '\n' in filename:
p = automaton_stream_parser(filename, "<string>", True) p = automaton_stream_parser(filename, "<string>", True)
...@@ -388,11 +400,11 @@ def automata(*sources, timeout=None): ...@@ -388,11 +400,11 @@ def automata(*sources, timeout=None):
if proc is not None: if proc is not None:
if not a: if not a:
# We reached the end of the stream. Wait for the # We reached the end of the stream. Wait for the
# process to finish, so that we can its exit code. # process to finish, so that we get its exit code.
ret = proc.wait() ret = proc.wait()
else: else:
# if a != None, we probably got there through an # if a != None, we probably got there through an
# exception, and the subprocess my still be # exception, and the subprocess might still be
# running. Check if an exit status is available # running. Check if an exit status is available
# just in case. # just in case.
ret = proc.poll() ret = proc.poll()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment