forked from runtimeverification/k
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathRunProcess.java
More file actions
92 lines (70 loc) · 2.89 KB
/
RunProcess.java
File metadata and controls
92 lines (70 loc) · 2.89 KB
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
// Copyright (c) 2012-2019 K Team. All Rights Reserved.
package org.kframework.krun;
import org.kframework.utils.errorsystem.KEMException;
import org.apache.commons.io.IOUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Map;
import java.util.Scanner;
import java.util.function.Supplier;
// instantiate processes
public class RunProcess {
/**
* Returns a thread that pipes all incoming data from {@param in} to {@param out}.
* @param in A function that returns the input stream to be piped to {@param out}
* @param out The output stream to pipe data to.
* @return A {@link Thread} that will pipe all data from {@param in} to {@param out} until EOF is reached.
*/
public static Thread getOutputStreamThread(Supplier<InputStream> in, PrintStream out) {
return new Thread(() -> {
try {
IOUtils.copy(in.get(), out);
} catch (IOException e) {}
});
}
public static class ProcessOutput {
public final byte[] stdout;
public final byte[] stderr;
public final int exitCode;
public ProcessOutput(byte[] stdout, byte[] stderr, int exitCode) {
this.stdout = stdout;
this.stderr = stderr;
this.exitCode = exitCode;
}
}
private RunProcess() {}
public static ProcessOutput execute(Map<String, String> environment, ProcessBuilder pb, String... commands) {
try {
if (commands.length <= 0) {
throw KEMException.criticalError("Need command options to run");
}
// create process
pb = pb.command(commands);
Map<String, String> realEnvironment = pb.environment();
realEnvironment.putAll(environment);
// start process
Process process = pb.start();
ByteArrayOutputStream out, err;
PrintStream outWriter, errWriter;
out = new ByteArrayOutputStream();
err = new ByteArrayOutputStream();
outWriter = new PrintStream(out);
errWriter = new PrintStream(err);
Thread outThread = getOutputStreamThread(process::getInputStream, outWriter);
Thread errThread = getOutputStreamThread(process::getErrorStream, errWriter);
outThread.start();
errThread.start();
// wait for process to finish
process.waitFor();
outThread.join();
errThread.join();
outWriter.flush();
errWriter.flush();
return new ProcessOutput(out.toByteArray(), err.toByteArray(), process.exitValue());
} catch (IOException | InterruptedException e) {
throw KEMException.criticalError("Error while running process:" + e.getMessage(), e);
}
}
}