Example #1
0
    def __init__(self, arguments, name=None, env=-1, cwd=None, output_to_shell=False, use_logfiles=True):

        command_safe = False

        if type(arguments) in (list, tuple):
            self.command = escape_arguments_to_string(arguments)
            command_safe = True
        else:
            self.command = arguments[:]

        self.start_time = time.localtime()

        kwargs = {}
        if env == -1:
            kwargs['env'] = common.copy(common.ENV)
        else:
            kwargs['env'] = env
        if cwd is not None:
            kwargs['cwd'] = cwd
        if output_to_shell:
            kwargs['stdin'] = sys.stdin
            kwargs['stdout'] = sys.stdout
            kwargs['stderr'] = sys.stderr
        elif use_logfiles:
            # If we are not outputting to the shell
            # the output will be routed to two files in /tmp.
            conf_name = util.string_safe_chars(
                env.get('WINEPREFIXNAME', common.ENV.get('WINEPREFIXNAME', ''))
            )

            self.log_filename_base = '%s-%s-%s' % (
                conf_name,
                time.strftime('%Y-%m-%d-%H:%M:%S', self.start_time),
                util.string_random()
            )
            self.log_filename_out = '{tmppath}/run-process-{filename}.out'.format(
                tmppath = common.ENV['VINEYARDTMP'], filename = self.log_filename_base)
            self.log_filename_err = '{tmppath}/run-process-{filename}.err'.format(
                tmppath = common.ENV['VINEYARDTMP'], filename = self.log_filename_base)
            self.log_out_last_pos = 0
            self.log_err_last_pos = 0

            if command_safe:
                self.command = "%s 2>%s 1>%s" % (
                    self.command,
                    self.log_filename_err,
                    self.log_filename_out
                )
            else:
                self.command = "%s 2>%s 1>%s" % (
                    util.string_safe_shell(self.command),
                    self.log_filename_err,
                    self.log_filename_out
                )

        # Use a new process group for this process
        if 'preexec_fn' not in kwargs:
            kwargs['preexec_fn'] = os.setpgrp

        if 'env' in kwargs:
            self.shell = common.which(['dash', 'bash', 'sh'], kwargs['env'])
        else:
            self.shell = common.which(['dash', 'bash', 'sh'])

        print("Going to run:", self.shell, '-c', '--', 'exec %s' % self.command)

        self.child = Popen([
            self.shell, '-c', '--', 'exec %s' % self.command
        ], **kwargs)
        print("Running:", self.shell, '-c', '--', 'exec %s' % self.command)

        self._kwargs = kwargs

        self.pid = self.child.pid
        self.returncode = self.child.returncode
        self.send_signal = self.child.send_signal
        self.terminate = self.child.terminate
        self.kill = self.child.kill
Example #2
0
class run:
    log_filename_out = None
    log_filename_err = None

    def __init__(self, arguments, name=None, env=-1, cwd=None, output_to_shell=False, use_logfiles=True):

        command_safe = False

        if type(arguments) in (list, tuple):
            self.command = escape_arguments_to_string(arguments)
            command_safe = True
        else:
            self.command = arguments[:]

        self.start_time = time.localtime()

        kwargs = {}
        if env == -1:
            kwargs['env'] = common.copy(common.ENV)
        else:
            kwargs['env'] = env
        if cwd is not None:
            kwargs['cwd'] = cwd
        if output_to_shell:
            kwargs['stdin'] = sys.stdin
            kwargs['stdout'] = sys.stdout
            kwargs['stderr'] = sys.stderr
        elif use_logfiles:
            # If we are not outputting to the shell
            # the output will be routed to two files in /tmp.
            conf_name = util.string_safe_chars(
                env.get('WINEPREFIXNAME', common.ENV.get('WINEPREFIXNAME', ''))
            )

            self.log_filename_base = '%s-%s-%s' % (
                conf_name,
                time.strftime('%Y-%m-%d-%H:%M:%S', self.start_time),
                util.string_random()
            )
            self.log_filename_out = '{tmppath}/run-process-{filename}.out'.format(
                tmppath = common.ENV['VINEYARDTMP'], filename = self.log_filename_base)
            self.log_filename_err = '{tmppath}/run-process-{filename}.err'.format(
                tmppath = common.ENV['VINEYARDTMP'], filename = self.log_filename_base)
            self.log_out_last_pos = 0
            self.log_err_last_pos = 0

            if command_safe:
                self.command = "%s 2>%s 1>%s" % (
                    self.command,
                    self.log_filename_err,
                    self.log_filename_out
                )
            else:
                self.command = "%s 2>%s 1>%s" % (
                    util.string_safe_shell(self.command),
                    self.log_filename_err,
                    self.log_filename_out
                )

        # Use a new process group for this process
        if 'preexec_fn' not in kwargs:
            kwargs['preexec_fn'] = os.setpgrp

        if 'env' in kwargs:
            self.shell = common.which(['dash', 'bash', 'sh'], kwargs['env'])
        else:
            self.shell = common.which(['dash', 'bash', 'sh'])

        print("Going to run:", self.shell, '-c', '--', 'exec %s' % self.command)

        self.child = Popen([
            self.shell, '-c', '--', 'exec %s' % self.command
        ], **kwargs)
        print("Running:", self.shell, '-c', '--', 'exec %s' % self.command)

        self._kwargs = kwargs

        self.pid = self.child.pid
        self.returncode = self.child.returncode
        self.send_signal = self.child.send_signal
        self.terminate = self.child.terminate
        self.kill = self.child.kill

    def communicate(self):
        """
        Wait for the child process to finish, then return the stdout and stderr
        of it as a tuple in the form of (stdout, stderr)."""
        if self.child.returncode != None: # Process has finished
            return None

        if self.log_filename_out == None:
            return self.child.communicate()
        else:
            self.child.communicate()
            return self.read(with_stdout=True, with_stderr=True, since_last=True)

    def read(self, size=-1, with_stdout = True, with_stderr = True, since_last=False):
        """
        Read the stdout and/or stderr of the child process.
        If since_last is true only the output given since the last read is returned.
        If since_last is false the entire output stream is returned."""
        return _read(self, size=size, with_stdout=with_stdout, with_stderr=with_stderr, since_last=since_last)

    def read_stdout(self, since_last=False):
        return self.read(with_stdout = True, with_stderr = False, since_last = since_last)

    def read_stderr(self, since_last=False):
        return self.read(with_stderr = True, with_stdout = False, since_last = since_last)

    def poll(self):
        """
        Check if child process has terminated. Set and return returncode attribute."""
        # poll() has already been run, return the already given returncode
        if self.returncode != None:
            return self.returncode

        self.returncode = self.child.poll()
        # If process has terminated, delete it's object so the process can be freed
        if self.returncode != None:
            del self.child
            self.child = None
        return self.returncode