...
Code Block | ||
---|---|---|
| ||
class Exec extends Thread { InputStream is; String type; OutputStream os; Exec(InputStream is, String type) { this(is, type, null); } Exec(InputStream is, String type, OutputStream redirect) { this.is = is; this.type = type; this.os = redirect; } public void run() { try { PrintWriter pw = null; if (os != null) { pw = new PrintWriter(os); } InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line=null; while ( (line = br.readLine()) != null) { if (pw != null) { pw.println(line); pw.flush(); } System.out.println(type + ">" + line); } if (pw != null) pw.flush(); } catch (IOException ioe) { /* Forward to handler */ } } } public class ExecMe { public static void main(String[] args) { // ... perform command argument check ... try { FileOutputStream fos = new FileOutputStream("c:\\output.txt"); Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("notemaker"); // any error message? Exec errorGobbler = new Exec(proc.getErrorStream(), "ERROR"); // any output? Exec outputGobbler = new Exec(proc.getInputStream(), "OUTPUT", fos); errorGobbler.start(); outputGobbler.start(); // any error? int exitVal = proc.waitFor(); errorGobbler.join(); // handle condition where the outputGobbler.join(); // process ends before the threads finish fos.flush(); fos.close(); } catch (Throwable t) { /* forward to handler */ } } } |
Compliant Solution (3)
This complint solution (based on the Sun forums query Runtime.exec hangs even If I drain output), uses the ProcessBuilder
to merge the error and output streams to simplify the handling mechanism. The readToPrompt()
method interacts with the command prompt and reads the output of the invoked process.
Code Block | ||
---|---|---|
| ||
public class Cmd {
public static void main(String[] args) throws IOException {
ProcessBuilder pb = new ProcessBuilder("cmd");
pb = pb.redirectErrorStream(true);
Process p = pb.start();
InputStream is = p.getInputStream();
OutputStream os = p.getOutputStream();
PrintWriter pw = new PrintWriter(os, true);
readToPrompt(is);
pw.println("dir");
readToPrompt(is);
}
private static void readToPrompt(InputStream is) throws IOException {
String s = "";
for (;;) {
int i = is.read();
if (i < 0) {
System.out.println();
System.out.println("EOF");
System.exit(0);
}
char c = (char)i;
s += c;
if (s.endsWith("\r\n") {
System.out.print(s);
s = "";
}
// detects prompt, to break out
if (c == '>' && s.length() > 2 && s.charAt(1) == ':') {
System.out.print(s);
break;
}
}
}
}
|
Risk Assessment
Misuse of the exec()
method can result in runtime exceptions and denial of service vulnerabilities.
...