1 /**
2 Includes a utility class for unix-pipe chaining of system processes.
3 */4 moduledscord.util.process;
5 6 importstd.algorithm.iteration,
7 std.array;
8 9 staticimportstd.stdio,
10 std.process;
11 12 /**
13 Represents a single running process in the chain.
14 */15 structProcess {
16 std.process.Pidpid;
17 std.process.Pipe_stdout;
18 std.process.Pipe_stderr;
19 20 /**
21 Creates a new process (and spawns it).
22 23 Params:
24 args = args for the process
25 upstream = file object used as stdin for the process
26 */27 this(string[] args, std.stdio.Fileupstream) {
28 this._stdout = std.process.pipe();
29 this._stderr = std.process.pipe();
30 this.pid = std.process.spawnProcess(args, upstream, this._stdout.writeEnd, this._stderr.writeEnd);
31 }
32 33 /**
34 Creates a new process (and spawns it)
35 36 Params:
37 args = args for the process
38 */39 this(string[] args) {
40 this(args, std.stdio.stdin);
41 }
42 43 /// Waits for this process to complete and returns the exit code.44 intwait() {
45 returnstd.process.wait(this.pid);
46 }
47 48 /// File object of this processes stdout49 @propertystd.stdio.Filestdout() {
50 returnthis._stdout.readEnd;
51 }
52 53 /// File object of this processes stderr54 @propertystd.stdio.Filestderr() {
55 returnthis._stderr.readEnd;
56 }
57 }
58 59 /**
60 Represents a chain of processes with each member piping its stdout into the
61 next members stdin.
62 */63 classProcessChain {
64 Process*[] members;
65 66 /// Adds a new process in the chain.67 ProcessChainrun(string[] args) {
68 members ~= newProcess(args,
69 this.members.length ? this.members[$-1]._stdout.readEnd : std.stdio.stdin);
70 returnthis;
71 }
72 73 /// Waits for all processes in the chain to exit and returns an array of exit codes.74 int[] wait() {
75 assert(this.members.length);
76 returnthis.members.map!((p) => p.wait()).array;
77 }
78 79 /// Returns stdout for the last process in the chain.80 std.stdio.Fileend() {
81 assert(this.members.length);
82 returnthis.members[$-1]._stdout.readEnd;
83 }
84 }