__all__ = ['getProcessOutput'] import weakref from twisted.internet.utils import _BackRelay from twisted.internet import defer, reactor from twisted.internet.defer import TimeoutError DEFAULT_ENV = { 'PATH': '/opt/bin:/opt/local/bin:/usr/bin:/bin:/usr/local/bin:' '/usr/local/sbin:/sbin:/usr/sbin', } class SafeBackRelay(_BackRelay): def errReceived(self, *args, **kwds): if self.deferred is not None: return _BackRelay.errReceived(self, *args, **kwds) def _callProtocolWithDeferred(protocol, executable, args, env, path, reactor, mode='r', timeout=None): if mode == 'r': childFDs = {1: 'r', 2: 'r'} elif mode == 'w': childFDs = {0: 'w'} else: childFDs = {0: 'w', 1: 'r', 2: 'r'} d = defer.Deferred() p = protocol(d) proc = reactor.spawnProcess(p, executable, (executable,)+tuple(args), env, path, childFDs=childFDs) d.process = weakref.proxy(proc) d.timeout = False if timeout is not None: def timeoutProcess(): if not d.called: d.timeout = True p.transport.signalProcess('TERM') reactor.callLater(timeout, timeoutProcess) return d def getProcessOutput(executable, args=(), env=DEFAULT_ENV, path='.', reactor=reactor, mode='r', timeout=None): return _callProtocolWithDeferred(SafeBackRelay, executable, args, env, path, reactor, mode, timeout)