commit f62fc95876fa2c817b7e1aa2a57fe6bd93ef7a78 Author: Damian Johnson atagar@torproject.org Date: Fri May 26 13:42:30 2017 -0700
Allow interpreter to continue after tor shutsdown
When tor shuts down the next tor-prompt command immediately terminates the interpreter. This is both unnecessary and sucks. We provide more than a control connection and should let users continue to issue those commans after tor's gone.
https://www.atagar.com/transfer/stem/interpreter_shutdown_prompt.png
Neat idea suggested by teor...
https://trac.torproject.org/projects/tor/ticket/22374 --- docs/change_log.rst | 1 + stem/interpreter/__init__.py | 13 +++++++++++++ stem/interpreter/commands.py | 3 --- 3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/docs/change_log.rst b/docs/change_log.rst index a097f5d..a372e0c 100644 --- a/docs/change_log.rst +++ b/docs/change_log.rst @@ -72,6 +72,7 @@ The following are only available within Stem's `git repository * **Interpreter**
* Added a `'--run [command or path]' argument <tutorials/down_the_rabbit_hole.html#running-individual-commands>`_ to invoke specific commands (:trac:`21541`) + * Allowing interpreter to continue after tor shutsdown (:trac:`22374`)
.. _version_1.5:
diff --git a/stem/interpreter/__init__.py b/stem/interpreter/__init__.py index 033d819..b5d9c49 100644 --- a/stem/interpreter/__init__.py +++ b/stem/interpreter/__init__.py @@ -124,6 +124,7 @@ def main(): readline.set_completer_delims('\n')
interpreter = stem.interpreter.commands.ControlInterpreter(controller) + showed_close_confirmation = False
if args.run_cmd: if args.run_cmd.upper().startswith('SETEVENTS '): @@ -168,6 +169,18 @@ def main(): prompt = '... ' if interpreter.is_multiline_context else PROMPT user_input = input(prompt) if stem.prereq.is_python_3() else raw_input(prompt) interpreter.run_command(user_input, print_response = True) + except stem.SocketClosed as exc: + if showed_close_confirmation: + print(format("Unable to run tor commands. The control connection has been closed.", *ERROR_OUTPUT)) + else: + prompt = format("Tor's control port has closed. Do you want to continue this interpreter? (y/n) ", *HEADER_BOLD_OUTPUT) + user_input = input(prompt) if stem.prereq.is_python_3() else raw_input(prompt) + print('') # blank line + + if user_input.lower() in ('y', 'yes'): + showed_close_confirmation = True + else: + break except (KeyboardInterrupt, EOFError, stem.SocketClosed) as exc: print('') # move cursor to the following line break diff --git a/stem/interpreter/commands.py b/stem/interpreter/commands.py index 4d845a0..22558aa 100644 --- a/stem/interpreter/commands.py +++ b/stem/interpreter/commands.py @@ -309,9 +309,6 @@ class ControlInterpreter(code.InteractiveConsole): :raises: **stem.SocketClosed** if the control connection has been severed """
- if not self._controller.is_alive(): - raise stem.SocketClosed() - # Commands fall into three categories: # # * Interpreter commands. These start with a '/'.