[tor-commits] [arm/master] Better handling for QUIT signals

atagar at torproject.org atagar at torproject.org
Mon Sep 19 04:46:18 UTC 2011


commit e937fc31380a7a4a486ce0807dc1293ca8b151b9
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Sep 17 16:54:46 2011 -0700

    Better handling for QUIT signals
    
    The prompt was naively assuming that the control connection was still alive
    when handling input, and not properly shutting down the control connection in
    case of '/quit'.
---
 src/cli/interpretorPanel.py |    5 ++++-
 src/util/torInterpretor.py  |   24 +++++++++++++++++++++---
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/src/cli/interpretorPanel.py b/src/cli/interpretorPanel.py
index cc8b496..283c371 100644
--- a/src/cli/interpretorPanel.py
+++ b/src/cli/interpretorPanel.py
@@ -5,7 +5,7 @@ information, tab completion, and other usability features.
 
 import curses
 
-from util import panel, textInput, torInterpretor, uiTools
+from util import panel, textInput, torInterpretor, torTools, uiTools
 
 USAGE_INFO = "to use this panel press enter"
 PROMPT_LINE = [torInterpretor.PROMPT, (USAGE_INFO, torInterpretor.USAGE_FORMAT)]
@@ -79,6 +79,9 @@ class InterpretorPanel(panel.Panel):
         try:
           inputEntry, outputEntry = self.interpretor.handleQuery(input)
         except torInterpretor.InterpretorClosed:
+          # Makes our control connection check if its been closed or not
+          torTools.getConn().isAlive()
+          
           isDone = True
       
       if isDone:
diff --git a/src/util/torInterpretor.py b/src/util/torInterpretor.py
index 1cc66bd..6781b83 100644
--- a/src/util/torInterpretor.py
+++ b/src/util/torInterpretor.py
@@ -595,6 +595,12 @@ class ControlInterpretor:
       input - user input to be processed
     """
     
+    conn = torTools.getConn()
+    
+    # abort if the control connection has been severed
+    if not conn.isAlive():
+      raise InterpretorClosed("Control connection has been closed")
+    
     input = input.strip()
     
     # appends new input, cropping if too long
@@ -603,7 +609,6 @@ class ControlInterpretor:
     if backlogCrop > 0: self.backlog = self.backlog[backlogCrop:]
     
     inputEntry, outputEntry = [PROMPT], []
-    conn = torTools.getConn()
     
     # input falls into three general categories:
     # - interpretor command which starts with a '/'
@@ -684,6 +689,9 @@ class ControlInterpretor:
         try:
           response = conn.getTorCtl().sendAndRecv("%s\r\n" % input)
           
+          if cmd == "QUIT":
+            raise InterpretorClosed("Closing the connection")
+          
           for entry in response:
             # Response entries are tuples with the response code, body, and
             # extra info. For instance:
@@ -692,13 +700,17 @@ class ControlInterpretor:
             if len(entry) == 3:
               outputEntry.append((entry[1], OUTPUT_FORMAT))
         except Exception, exc:
-          outputEntry.append((str(exc), ERROR_FORMAT))
+          if isinstance(exc, InterpretorClosed):
+            raise exc
+          else:
+            outputEntry.append((str(exc), ERROR_FORMAT))
     
     # converts to lists split on newlines
     inputLines = _splitOnNewlines(inputEntry)
     outputLines = _splitOnNewlines(outputEntry)
     
     # appends new contents, cropping if too long
+    # TODO: it would be nice if InterpretorClosed exceptions were added to the content too
     self.contents += inputLines + outputLines
     cropLines = len(self.contents) - CONTENT_LIMIT
     if cropLines > 0: self.contents = self.contents[cropLines:]
@@ -745,11 +757,17 @@ def prompt():
     try:
       input = raw_input(prompt)
       _, outputEntry = interpretor.handleQuery(input)
-    except:
+    except Exception, exc:
+      if isinstance(exc, InterpretorClosed) and str(exc):
+        print format(str(exc), *ERROR_FORMAT)
+      
       # moves cursor to the next line and terminates (most commonly
       # KeyboardInterrupt and EOFErro)
       print
       
+      torTools.NO_SPAWN = True
+      torTools.getConn().close()
+      
       # stop daemons
       hostnames.stop()
       





More information about the tor-commits mailing list