Last active
March 15, 2020 17:39
-
-
Save eed3si9n/df6286924782334accd9ecb2a94c41ac to your computer and use it in GitHub Desktop.
A lot might not be needed post Java 1.7.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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