summaryrefslogtreecommitdiff
path: root/lib/astal/io/process.vala
blob: e8637abd3cdd350e0868cf598557400e5d32a038 (plain)
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
public class AstalIO.Process : Object {
    private void read_stream(DataInputStream stream, bool err) {
        stream.read_line_utf8_async.begin(Priority.DEFAULT, null, (_, res) => {
            try {
                var output = stream.read_line_utf8_async.end(res);
                if (output != null) {
                    if (err)
                        stdout(output.strip());
                    else
                        stderr(output.strip());

                    read_stream(stream, err);
                }
            } catch (Error err) {
                printerr("%s\n", err.message);
            }
        });
    }

    private DataInputStream out_stream;
    private DataInputStream err_stream;
    private DataOutputStream in_stream;
    private Subprocess process;
    public string[] argv { construct; get; }

    public signal void stdout (string out);
    public signal void stderr (string err);

    public void kill() {
        process.force_exit();
    }

    public void signal(int signal_num) {
        process.send_signal(signal_num);
    }

    public void write(string in) throws Error {
        in_stream.put_string(in);
    }

    public void write_async(string in) {
        in_stream.write_all_async.begin(
            in.data,
            Priority.DEFAULT, null, (_, res) => {
                try {
                    in_stream.write_all_async.end(res, null);
                } catch (Error err) {
                    printerr("%s\n", err.message);
                }
            }
        );
    }

    public Process.subprocessv(string[] cmd) throws Error {
        Object(argv: cmd);
        process = new Subprocess.newv(cmd,
            SubprocessFlags.STDIN_PIPE |
            SubprocessFlags.STDERR_PIPE |
            SubprocessFlags.STDOUT_PIPE
        );
        out_stream = new DataInputStream(process.get_stdout_pipe());
        err_stream = new DataInputStream(process.get_stderr_pipe());
        in_stream = new DataOutputStream(process.get_stdin_pipe());
        read_stream(out_stream, true);
        read_stream(err_stream, false);
    }

    public static Process subprocess(string cmd) throws Error {
        string[] argv;
        Shell.parse_argv(cmd, out argv);
        return new Process.subprocessv(argv);
    }

    public static string execv(string[] cmd) throws Error {
        var process = new Subprocess.newv(
            cmd,
            SubprocessFlags.STDERR_PIPE |
            SubprocessFlags.STDOUT_PIPE
        );

        string err_str, out_str;
        process.communicate_utf8(null, null, out out_str, out err_str);
        var success = process.get_successful();
        process.dispose();
        if (success)
            return out_str.strip();
        else
            throw new IOError.FAILED(err_str.strip());
    }

    public static string exec(string cmd) throws Error {
        string[] argv;
        Shell.parse_argv(cmd, out argv);
        return Process.execv(argv);
    }

    public static async string exec_asyncv(string[] cmd) throws Error {
        var process = new Subprocess.newv(
            cmd,
            SubprocessFlags.STDERR_PIPE |
            SubprocessFlags.STDOUT_PIPE
        );

        string err_str, out_str;
        yield process.communicate_utf8_async(null, null, out out_str, out err_str);
        var success = process.get_successful();
        process.dispose();
        if (success)
            return out_str.strip();
        else
            throw new IOError.FAILED(err_str.strip());
    }

    public static async string exec_async(string cmd) throws Error {
        string[] argv;
        Shell.parse_argv(cmd, out argv);
        return yield exec_asyncv(argv);
    }
}