[tor-commits] [stem/master] Have get_connections() resolve the pid if not provided with one

atagar at torproject.org atagar at torproject.org
Thu Jan 28 17:25:01 UTC 2016


commit 949e59ffcf2eb09495ec7b42672598af5e0bb656
Author: Damian Johnson <atagar at torproject.org>
Date:   Thu Jan 28 09:20:30 2016 -0800

    Have get_connections() resolve the pid if not provided with one
    
    Three of our connection resolvers require a pid to function. When provided with
    a process name instead we raised a ValueError, but we can at least *try* to
    resolve the name to a pid. If unsuccessful we now raise an IOError. Thanks to
    toralf for suggesting this change.
---
 stem/util/connection.py |   20 ++++++++++++++------
 test/unit/manual.py     |    2 +-
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/stem/util/connection.py b/stem/util/connection.py
index cbc6ac2..e72bd12 100644
--- a/stem/util/connection.py
+++ b/stem/util/connection.py
@@ -166,14 +166,16 @@ def get_connections(resolver, process_pid = None, process_name = None):
   :returns: **list** of :class:`~stem.util.connection.Connection` instances
 
   :raises:
-    * **ValueError** if using **Resolver.PROC** or **Resolver.BSD_PROCSTAT**
-      and the process_pid wasn't provided
+    * **ValueError** if neither a process_pid nor process_name is provided
 
     * **IOError** if no connections are available or resolution fails
       (generally they're indistinguishable). The common causes are the
       command being unavailable or permissions.
   """
 
+  if not process_pid and not process_name:
+    raise ValueError('You must provide a pid or process name to provide connections for')
+
   def _log(msg):
     if LOG_CONNECTION_RESOLUTION:
       log.debug(msg)
@@ -187,11 +189,17 @@ def get_connections(resolver, process_pid = None, process_name = None):
     except ValueError:
       raise ValueError('Process pid was non-numeric: %s' % process_pid)
 
-  if process_pid is None and process_name and resolver == Resolver.NETSTAT_WINDOWS:
-    process_pid = stem.util.system.pid_by_name(process_name)
+  if process_pid is None:
+    all_pids = stem.util.system.pid_by_name(process_name, True)
 
-  if process_pid is None and resolver in (Resolver.NETSTAT_WINDOWS, Resolver.PROC, Resolver.BSD_PROCSTAT):
-    raise ValueError('%s resolution requires a pid' % resolver)
+    if len(all_pids) == 0:
+      if resolver in (Resolver.NETSTAT_WINDOWS, Resolver.PROC, Resolver.BSD_PROCSTAT):
+        raise IOError("Unable to determine the pid of '%s'. %s requires the pid to provide the connections." % (process_name, resolver))
+    elif len(all_pids) == 1:
+      process_pid = all_pids[0]
+    else:
+      if resolver in (Resolver.NETSTAT_WINDOWS, Resolver.PROC, Resolver.BSD_PROCSTAT):
+        raise IOError("There's multiple processes named '%s'. %s requires a single pid to provide the connections." % (process_name, resolver))
 
   if resolver == Resolver.PROC:
     return [Connection(*conn) for conn in stem.util.proc.connections(process_pid)]
diff --git a/test/unit/manual.py b/test/unit/manual.py
index 8711fb7..99628b0 100644
--- a/test/unit/manual.py
+++ b/test/unit/manual.py
@@ -238,7 +238,7 @@ class TestManual(unittest.TestCase):
   @patch('tempfile.mkdtemp', Mock(return_value = '/no/such/path'))
   @patch('shutil.rmtree', Mock())
   @patch('stem.manual.open', Mock(return_value = io.BytesIO()), create = True)
-  @patch('stem.util.system.call', Mock(side_effect = OSError('call failed')))
+  @patch('stem.util.system.call', Mock(side_effect = stem.util.system.CallError('call failed', 'a2x -f manpage /no/such/path/tor.1.txt', 1, None, None, 'call failed')))
   @patch('stem.util.system.is_available', Mock(return_value = True))
   @patch(URL_OPEN, Mock(return_value = io.BytesIO(b'test content')))
   def test_download_man_page_when_a2x_fails(self):





More information about the tor-commits mailing list