package org.checkerframework.framework.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.Arrays;
public class ExecUtil {
public static int execute(final String[] cmd, final OutputStream std, final OutputStream err) {
final Redirection outRedirect = new Redirection(std, BLOCK_SIZE);
final Redirection errRedirect = new Redirection(err, BLOCK_SIZE);
try {
final Process proc = Runtime.getRuntime().exec(cmd);
outRedirect.redirect(proc.getInputStream());
errRedirect.redirect(proc.getErrorStream());
final IOException stdExc = outRedirect.join();
final IOException errExc = errRedirect.join();
final int exitStatus = proc.waitFor();
if (stdExc != null) {
throw stdExc;
}
if (errExc != null) {
throw errExc;
}
return exitStatus;
} catch (InterruptedException e) {
throw new RuntimeException(
"Exception executing command: " + PluginUtil.join(" ", Arrays.asList(cmd)), e);
} catch (IOException e) {
throw new RuntimeException(
"Exception executing command: " + PluginUtil.join(" ", Arrays.asList(cmd)), e);
}
}
public static final int BLOCK_SIZE = 1024;
public static class Redirection {
private final char[] buffer;
private final OutputStreamWriter out;
private Thread thread;
private IOException exception;
public Redirection(final OutputStream out, final int bufferSize) {
this.buffer = new char[bufferSize];
this.out = new OutputStreamWriter(out);
}
public void redirect(final InputStream inStream) {
exception = null;
this.thread =
new Thread(
new Runnable() {
@Override
public void run() {
final InputStreamReader in = new InputStreamReader(inStream);
try {
int read = 0;
while (read > -1) {
read = in.read(buffer);
if (read > 0) {
out.write(buffer, 0, read);
}
}
out.flush();
} catch (IOException exc) {
exception = exc;
} finally {
quietlyClose(in);
}
}
});
thread.start();
}
public IOException join() throws InterruptedException {
thread.join();
return exception;
}
}
public static void quietlyClose(final Writer writer) {
try {
writer.close();
} catch (IOException ioExc) {
}
}
public static void quietlyClose(final Reader reader) {
try {
reader.close();
} catch (IOException ioExc) {
}
}
}