about summary refs log tree commit diff stats
path: root/ranger/ext/spawn.py
blob: 393d48d955ef5347005173f82b325c0b79796bba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# This file is part of ranger, the console file manager.
# License: GNU GPL version 3, see the file "AUTHORS" for details.

from subprocess import Popen, PIPE, CalledProcessError
ENCODING = 'utf-8'


def spawn(*args, **kwargs):
    """Runs a program, waits for its termination and returns its stdout

    This function is similar to python 2.7's subprocess.check_output,
    but is favored due to python 2.6 compatibility.

    The arguments may be:

        spawn(string)
        spawn(command, arg1, arg2...)
        spawn([command, arg1, arg2])

    The string will be run through a shell, otherwise the command is executed
    directly.

    The keyword argument "decode" determines if the output shall be decoded
    with the encoding '%s'.

    Further keyword arguments are passed to Popen.
    """ % (ENCODING, )

    if len(args) == 1:
        popen_arguments = args[0]
        shell = isinstance(popen_arguments, str)
    else:
        popen_arguments = args
        shell = False

    if 'decode' in kwargs:
        do_decode = kwargs['decode']
        del kwargs['decode']
    else:
        do_decode = True
    if 'stdout' not in kwargs:
        kwargs['stdout'] = PIPE
    if 'shell' not in kwargs:
        kwargs['shell'] = shell

    process = Popen(popen_arguments, **kwargs)
    stdout, stderr = process.communicate()
    return_value = process.poll()
    if return_value:
        error = CalledProcessError(return_value, popen_arguments[0])
        error.output = stdout
        raise error

    if do_decode:
        return stdout.decode(ENCODING)
    else:
        return stdout