]> scripts.mit.edu Git - wizard.git/blobdiff - wizard/shell.py
Remove string exception from remaster.
[wizard.git] / wizard / shell.py
index 687071205a14fe12a63557dc722a0b20f3195e24..b8d4bd1e6dcfa8cda550c192b63a74a3146a435c 100644 (file)
@@ -55,6 +55,7 @@ class Shell(object):
     """
     def __init__(self, dry = False):
         self.dry = dry
+        self.cwd = None
     def call(self, *args, **kwargs):
         """
         Performs a system call.  The actual executable and options should
@@ -127,7 +128,7 @@ class Shell(object):
         # ourself, and then setting up a
         # SIGCHILD handler to write a single byte to the pipe to get
         # us out of select() when a subprocess exits.
-        proc = subprocess.Popen(args, stdout=stdout, stderr=stderr, stdin=stdin)
+        proc = subprocess.Popen(args, stdout=stdout, stderr=stderr, stdin=stdin, cwd=self.cwd, )
         if self._async(proc, args, **kwargs):
             return proc
         stdout, stderr = proc.communicate(kwargs["input"])
@@ -194,6 +195,8 @@ class Shell(object):
         on working directory context.  Keyword arguments are the
         same as :meth:`call`.
         """
+        if os.getuid():
+            return self.call(*args, **kwargs)
         uid = os.stat(os.getcwd()).st_uid
         # consider also checking ruid?
         if uid != os.geteuid():
@@ -213,6 +216,12 @@ class Shell(object):
         """
         kwargs["strip"] = True
         return self.call(*args, **kwargs)
+    def setcwd(self, cwd):
+        """
+        Sets the directory processes are executed in. This sets a value
+        to be passed as the ``cwd`` argument to ``subprocess.Popen``.
+        """
+        self.cwd = cwd
 
 class ParallelShell(Shell):
     """
@@ -279,7 +288,7 @@ class ParallelShell(Shell):
         Blocking call that waits for an open subprocess slot.  This is
         automatically called by :meth:`Shell.call`.
         """
-        # XXX: This API sucks; the actuall call/callAsUser call should
+        # XXX: This API sucks; the actual call/callAsUser call should
         # probably block automatically (unless I have a good reason not to)
         # bail out immediately on initial ramp up
         if len(self.running) < self.max: return
@@ -313,6 +322,12 @@ class ParallelShell(Shell):
             return
         on_success(stdout, stderr)
 
+# Setup a convenience global instance
+shell = Shell()
+call = shell.call
+callAsUser = shell.callAsUser
+safeCall = shell.safeCall
+eval = shell.eval
 
 class DummyParallelShell(ParallelShell):
     """Same API as :class:`ParallelShell`, but doesn't actually