[tor-commits] [stem/master] General system utilities

atagar at torproject.org atagar at torproject.org
Mon Oct 10 17:10:27 UTC 2011


commit 1aff6b875213d70a05d0cb5d86a5ff9914ce6e41
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Oct 9 03:24:44 2011 -0700

    General system utilities
    
    Adding some simple utility functions that I'll need later. These are rewrites
    of their arm counterparts, which I wrote before discovering the subprocess
    module.
---
 stem/util/__init__.py |    2 +-
 stem/util/system.py   |  109 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 110 insertions(+), 1 deletions(-)

diff --git a/stem/util/__init__.py b/stem/util/__init__.py
index e079d62..b778b6f 100644
--- a/stem/util/__init__.py
+++ b/stem/util/__init__.py
@@ -2,5 +2,5 @@
 Utility functions used by the stem library.
 """
 
-__all__ = ["enum", "term"]
+__all__ = ["enum", "system", "term"]
 
diff --git a/stem/util/system.py b/stem/util/system.py
new file mode 100644
index 0000000..3c520e8
--- /dev/null
+++ b/stem/util/system.py
@@ -0,0 +1,109 @@
+"""
+Helper functions for working with the underlying system. These are mostly os
+dependent, only working on linux, osx, and bsd.
+"""
+
+import os
+import time
+import subprocess
+
+from stem.util import log
+
+# Mapping of commands to if they're available or not. This isn't always
+# reliable, failing for some special commands. For these the cache is
+# prepopulated to skip lookups.
+CMD_AVAILABLE_CACHE = {"ulimit": True}
+
+def is_available(command, cached=True):
+  """
+  Checks the current PATH to see if a command is available or not. If more
+  than one command is present (for instance "ls -a | grep foo") then this
+  just checks the first.
+  
+  Arguments:
+    command (str) - command to search for
+    cached (bool) - makes use of available cached results if True
+  
+  Returns:
+    True if an executable we can use by that name exists in the PATH, False
+    otherwise
+  """
+  
+  if " " in command: command = command.split(" ")[0]
+  
+  if cached and command in CMD_AVAILABLE_CACHE:
+    return CMD_AVAILABLE_CACHE[command]
+  else:
+    cmd_exists = False
+    for path in os.environ["PATH"].split(os.pathsep):
+      cmd_path = os.path.join(path, command)
+      
+      if os.path.exists(cmd_path) and os.access(cmd_path, os.X_OK):
+        cmd_exists = True
+        break
+    
+    CMD_AVAILABLE_CACHE[command] = cmd_exists
+    return cmd_exists
+
+def is_running(command, suppress_exc = True):
+  """
+  Checks for if a process with a given name is running or not.
+  
+  Arguments:
+    command (str)       - process name to be checked
+    suppress_exc (bool) - if True then None is returned on failure, otherwise
+                          this raises the exception
+  
+  Returns:
+    True if the process is running, False otherwise
+  
+  Raises:
+    OSError if this can't be determined and suppress_exc is False
+  """
+  
+  command_listing = call("ps -A co command")
+  
+  if command_listing:
+    return command in command_listing
+  else:
+    if suppress_exc: return None
+    else: raise OSError("Unable to check via 'ps -A co command'")
+
+def call(command, suppress_exc = True):
+  """
+  Issues a command in a subprocess, blocking until completion and returning the
+  results. This is not actually ran in a shell so pipes and other shell syntax
+  aren't permitted.
+  
+  Arguments:
+    command (str)       - command to be issued
+    suppress_exc (bool) - if True then None is returned on failure, otherwise
+                          this raises the exception
+  
+  Returns:
+    List with the lines of output from the command, None in case of failure if
+    suppress_exc is True
+  
+  Raises:
+    OSError if this fails and suppress_exc is False
+  """
+  
+  try:
+    start_time = time.time()
+    stdout, stderr = subprocess.Popen(command.split(), stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()
+    stdout, stderr = stdout.strip(), stderr.strip()
+    runtime = time.time() - start_time
+    
+    msg = "system call: %s (runtime: %0.2f)" % (command, runtime)
+    if stderr: msg += "\nstderr: %s" % stderr
+    log.log(log.DEBUG, msg)
+    
+    if stdout: return stdout.split("\n")
+    else: return []
+  except OSError, exc:
+    msg = "system call (failed): %s (error: %s)" % (command, exc)
+    log.log(log.INFO, msg)
+    
+    if suppress_exc: return None
+    else: raise exc
+





More information about the tor-commits mailing list