Skip to content

Instantly share code, notes, and snippets.

@froop
Last active July 4, 2021 10:42
Show Gist options
  • Save froop/b09dd1b687599e0cb1031f3fb6ce0fe2 to your computer and use it in GitHub Desktop.
Save froop/b09dd1b687599e0cb1031f3fb6ce0fe2 to your computer and use it in GitHub Desktop.
[Java] 外部プロセスが終了したら、それ以降の標準出力・エラー出力を捨てる
/*
* 外部プロセスが終了したら、それ以降の標準出力・エラー出力を捨てる。
* 参考: FIO07-J. 外部プロセスに IO バッファをブロックさせない - JPCERT/CC
* https://www.jpcert.or.jp/java-rules/fio07-j.html
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
class StreamGobbler extends Thread {
InputStream is;
PrintStream os;
boolean terminated;
StreamGobbler(InputStream is, PrintStream os) {
this.is = is;
this.os = os;
}
public void run() {
try {
StringBuilder buf = new StringBuilder();
while (true) {
while (is.available() == 0) {
if (terminated) {
return;
}
Thread.sleep(100);
}
char c;
if ((c = (char) is.read()) == -1) {
os.print(buf.toString());
return;
}
buf.append(c);
if (c == '\n') {
os.print(buf.toString());
buf = new StringBuilder();
}
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
void terminate() {
this.terminated = true;
}
}
public class CommandExec {
public static void main(String[] args) throws IOException, InterruptedException {
Process proc = Runtime.getRuntime().exec(args[0]);
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), System.err);
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), System.out);
errorGobbler.start();
outputGobbler.start();
int exitVal = proc.waitFor();
errorGobbler.terminate();
outputGobbler.terminate();
errorGobbler.join();
outputGobbler.join();
System.exit(exitVal);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment