/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
/**
* Test whether the Runtime.exec API works
*/
class TestRuntimeExec extends Thread {
public static void main(String[] argv) {
try {
int num = 1;
if (argv.length > 0) {
num = Integer.parseInt(argv[0]);
}
Thread[] threadList = new Thread[num];
for (int i = 0; i < num; ++i) {
threadList[i] = new TestRuntimeExec(i);
threadList[i].start();
}
for (int i = 0; i < num; ++i)
threadList[i].join();
System.out.println("All test threads finished");
} catch (Exception e) {
System.out.println("TestRuntimeExec: FAILED");
System.exit(1);
}
}
private static String[] testData = {
"This is a two line test file to see if we can call the Unix\n",
"`tee' command with Runtime.exec and get the expected result\n"
};
private int myNumber;
private int charsWritten = 0;
private int charsRead = 0;
private int charsExpected;
// Set this property to true on the command line
// to test interrupting a thread while it's blocked in
// Process.waitFor().
public static boolean interruptWait = Boolean.getBoolean("interruptWait");
public static final String PROGRAM = "tee";
TestRuntimeExec(int myNum) {
this.myNumber = myNum;
}
@Override
public void run() {
try {
charsExpected = 10000 * (testData[0].length() + testData[1].length());
String fileName = "/tmp/out" + myNumber;
final Process tac =
Runtime.getRuntime().exec(new String[]{PROGRAM, fileName}, null, new File("/tmp"));
Thread writer = new Thread() {
@Override
public void run() {
DataOutputStream stdin =
new DataOutputStream(tac.getOutputStream());
try {
for (int x = 0; x < 10000; x++) {
for (int i = 0; i < testData.length; i++) {
charsWritten += testData[i].length();
stdin.writeUTF(testData[i]);
}
}
stdin.flush();
stdin.close();
} catch (IOException e) {
throw new Error("TestRuntimeExec FAILED");
}
}
};
Thread reader = new Thread() {
@Override
public void run() {
DataInputStream stdout =
new DataInputStream(tac.getInputStream());
try {
for (int x = 0; x < 10000; x++) {
for (int i = 0; i < testData.length; i++) {
String in = stdout.readUTF();
charsRead += in.length();
if (! in.equals(testData[i]))
throw new Error("TestRuntimeExec FAILED: bad input " + in);
}
}
int exitCode = tac.waitFor();
if (exitCode == 0 &&
charsRead == charsExpected &&
charsWritten == charsExpected
)
System.err.println("TestRuntimeExec SUCCESS");
else
System.err.println("TestRuntimeExec FAILED");
//System.exit(exitCode);
} catch (Throwable e) {
e.printStackTrace();
throw new Error("TestRuntimeExec FAILED");
}
}
};
writer.start();
reader.start();
// Use Process.waitFor() to wait for the process to complete
final Thread waiter = new Thread() {
@Override
public void run() {
try {
int exitCode = tac.waitFor();
System.out.println("waitFor(): Process exited with code " + exitCode);
} catch (InterruptedException e) {
if (!interruptWait) {
System.out.println("Waiting thread uninterrupted unexpectedly!!!");
System.out.println("TestRuntimeExec FAILED");
System.exit(1);
}
System.out.println("Waiting thread interrupted! (THIS IS GOOD)");
e.printStackTrace();
}
}
};
waiter.start();
if (interruptWait) {
// See if waitFor() can be interrupted.
// This should not affect the behavoir of the IO threads
// or the process.
new Thread() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (Exception e) {
// ignore
}
waiter.interrupt();
}
}.start();
}
// Use repeated polling with exitValue() to wait for the process
// to complete
Thread poller = new Thread() {
@Override
public void run() {
int exitCode = -99;
boolean exited = false;
do {
try {
exitCode = tac.exitValue();
//System.out.println( "GOT IT");
exited = true;
} catch (IllegalThreadStateException e) {
System.out.println("still alive!");
try {
Thread.sleep(1000);
} catch (Exception ee) {
// ignore
}
}
}
while (!exited);
System.out.println("exitValue(): Process exited with code " + exitCode);
}
};
poller.start();
try {
reader.join();
writer.join();
waiter.join();
poller.join();
} catch (InterruptedException eee) {
eee.printStackTrace();
}
} catch (Throwable e) {
System.err.println("TestRuntimeExec FAILED with");
e.printStackTrace();
System.exit(1);
}
}
}