Skip to content

Instantly share code, notes, and snippets.

@eed3si9n
Last active March 15, 2020 17:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eed3si9n/df6286924782334accd9ecb2a94c41ac to your computer and use it in GitHub Desktop.
Save eed3si9n/df6286924782334accd9ecb2a94c41ac to your computer and use it in GitHub Desktop.
A lot might not be needed post Java 1.7.
/*
* sbt
* Licensed under Apache License 2.0 (see LICENSE)
*/
package org.scalasbt.sbtw;
import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.FilterInputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.function.IntSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.nio.ByteBuffer;
class SimpleProcessBuilder implements XProcessBuilder {
private ProcessBuilder p;
SimpleProcessBuilder(ProcessBuilder builder) {
this.p = builder;
}
public int waitAndExitValue() {
try {
return run().exitValue();
} catch (IOException e) {
return -1;
}
}
public XProcess run() throws IOException {
return run(BasicIO.standard(false));
}
public XProcess run(ProcessIO io) throws IOException {
Boolean inherited = io.inheritInput().apply(p);
Process process = p.start();
if (!inherited) {
Spawn.spawn(() -> {
io.writeInput().accept(process.getOutputStream());
return 0;
});
}
List<Thread> outputThreads = new LinkedList<Thread>();
Thread outThread = Spawn.spawn(() -> {
io.processOutput().accept(process.getInputStream());
return 0;
});
outputThreads.add(outThread);
if (!p.redirectErrorStream()) {
Thread errorThread = Spawn.spawn(() -> {
io.processOutput().accept(process.getInputStream());
return 0;
});
outputThreads.add(errorThread);
}
return new SimpleProcess(process, outputThreads);
}
@Override
public String toString() {
return p.command().toString();
}
class SimpleProcess implements XProcess {
private Process p;
private List<Thread> outputThreads;
SimpleProcess(Process p, List<Thread> outputThreads) {
this.p = p;
this.outputThreads = outputThreads;
}
@Override
public int exitValue() {
try {
p.waitFor();
for (Thread t: outputThreads) {
t.join();
}
} catch (InterruptedException e) {
p.destroy();
}
return p.exitValue();
}
@Override
public void destroy() {
p.destroy();
}
}
/** Utility to spawn a new thread.
*/
interface Spawn {
static Thread spawn(IntSupplier f) {
return spawn(f, false);
}
static Thread spawn(IntSupplier f, boolean daemon) {
Thread thread = new Thread() {
@Override
public void run() {
f.getAsInt();
}
};
thread.setDaemon(daemon);
thread.start();
return thread;
}
}
interface BasicIO {
static ProcessIO standard(boolean connectInput) {
return standard(input(connectInput), inheritInput(connectInput));
}
static ProcessIO standard(Consumer<OutputStream> in,
Function<ProcessBuilder, Boolean> inheritInput) {
return new ProcessIO(in, toStdOut(), toStdErr(), inheritInput);
}
static Consumer<OutputStream> input(boolean connectInput) {
return (OutputStream o) -> {
};
}
static Function<ProcessBuilder, Boolean> inheritInput(boolean connectInput) {
return (ProcessBuilder pb) -> {
if (connectInput) {
return InheritInput.of(pb);
}
else {
return false;
}
};
}
static Consumer<InputStream> toStdErr() {
return (InputStream in) -> transferFully(in, System.err);
}
static Consumer<InputStream> toStdOut() {
return (InputStream in) -> transferFully(in, System.out);
}
static void transferFully(InputStream in, OutputStream out) {
transferFullympl(in, out);
}
static void transferFullympl(InputStream in, OutputStream out) {
int continueCount = 1;
byte[] buffer = new byte[8192];
try {
int byteCount = in.read(buffer);
while (byteCount >= continueCount) {
out.write(buffer, 0, byteCount);
out.flush();
byteCount = in.read(buffer);
}
in.close();
} catch (IOException e) {
//
}
}
}
interface Uncloseable {
static InputStream of(InputStream in) {
return new FilterInputStream(in) {
@Override
public void close() {
}
};
}
static InputStream protect(InputStream in) {
if (in == System.in) {
return of(in);
} else {
return in;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment