diff --git a/avocado/utils/process.py b/avocado/utils/process.py index 87633dc2d4c51f4c3b08e8f7b8f204dd5c28eebc..52fe8b126afead841fbc20b5339d893372288e5d 100644 --- a/avocado/utils/process.py +++ b/avocado/utils/process.py @@ -242,35 +242,9 @@ class SubProcess(object): """ self.cmd = cmd self.verbose = verbose - if self.verbose: - log.info("Running '%s'", cmd) - self._popen = subprocess.Popen(cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - shell=True) self.allow_output_check = allow_output_check - self.start_time = time.time() - self.result = CmdResult(cmd) - self.stdout_file = StringIO.StringIO() - self.stderr_file = StringIO.StringIO() - self.stdout_lock = threading.Lock() - self.stdout_thread = threading.Thread(target=self._fd_drainer, - name="%s-stdout" % cmd, - args=[self._popen.stdout]) - self.stdout_thread.daemon = True - self.stderr_lock = threading.Lock() - self.stderr_thread = threading.Thread(target=self._fd_drainer, - name="%s-stderr" % cmd, - args=[self._popen.stderr]) - self.stderr_thread.daemon = True - self.stdout_thread.start() - self.stderr_thread.start() - - def signal_handler(signum, frame): - self.result.interrupted = True - self.wait() - - signal.signal(signal.SIGINT, signal_handler) + self.result = CmdResult(self.cmd) + self._popen = None def __str__(self): if self.result.exit_status is None: @@ -279,6 +253,36 @@ class SubProcess(object): rc = self.result.exit_status return 'SubProcess(cmd="%s", rc="%s")' % (self.cmd, rc) + def _init_subprocess(self): + if self._popen is None: + if self.verbose: + log.info("Running '%s'", self.cmd) + self._popen = subprocess.Popen(self.cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True) + self.start_time = time.time() + self.stdout_file = StringIO.StringIO() + self.stderr_file = StringIO.StringIO() + self.stdout_lock = threading.Lock() + self.stdout_thread = threading.Thread(target=self._fd_drainer, + name="%s-stdout" % self.cmd, + args=[self._popen.stdout]) + self.stdout_thread.daemon = True + self.stderr_lock = threading.Lock() + self.stderr_thread = threading.Thread(target=self._fd_drainer, + name="%s-stderr" % self.cmd, + args=[self._popen.stderr]) + self.stderr_thread.daemon = True + self.stdout_thread.start() + self.stderr_thread.start() + + def signal_handler(signum, frame): + self.result.interrupted = True + self.wait() + + signal.signal(signal.SIGINT, signal_handler) + def _fd_drainer(self, input_pipe): """ Read from input_pipe, storing and logging output. @@ -325,6 +329,7 @@ class SubProcess(object): lock.release() def _fill_results(self, rc): + self._init_subprocess() self.result.exit_status = rc if self.result.duration == 0: self.result.duration = time.time() - self.start_time @@ -350,6 +355,7 @@ class SubProcess(object): :return: Standard output of the process. :rtype: str """ + self._init_subprocess() self.stdout_lock.acquire() stdout = self.stdout_file.getvalue() self.stdout_lock.release() @@ -362,6 +368,7 @@ class SubProcess(object): :return: Standard error of the process. :rtype: str """ + self._init_subprocess() self.stderr_lock.acquire() stderr = self.stderr_file.getvalue() self.stderr_lock.release() @@ -371,12 +378,14 @@ class SubProcess(object): """ Send a :attr:`signal.SIGTERM` to the process. """ + self._init_subprocess() self.send_signal(signal.SIGTERM) def kill(self): """ Send a :attr:`signal.SIGKILL` to the process. """ + self._init_subprocess() self.send_signal(signal.SIGKILL) def send_signal(self, sig): @@ -385,12 +394,14 @@ class SubProcess(object): :param sig: Signal to send. """ + self._init_subprocess() self._popen.send_signal(sig) def poll(self): """ Call the subprocess poll() method, fill results if rc is not None. """ + self._init_subprocess() rc = self._popen.poll() if rc is not None: self._fill_results(rc) @@ -400,6 +411,7 @@ class SubProcess(object): """ Call the subprocess poll() method, fill results if rc is not None. """ + self._init_subprocess() rc = self._popen.wait() if rc is not None: self._fill_results(rc) @@ -416,6 +428,7 @@ class SubProcess(object): :returns: The command result object. :rtype: A :class:`avocado.utils.process.CmdResult` instance. """ + self._init_subprocess() start_time = time.time() if timeout is None: