Methods Summary |
---|
private static java.util.Vector | addVMSLogicals(java.util.Vector environment, java.io.BufferedReader in)This method is VMS specific and used by getProcEnvironment().
Parses VMS logicals from in and adds them to
environment . in is expected to be the
output of "SHOW LOGICAL". The method takes care of parsing the output
correctly as well as making sure that a logical defined in multiple
tables only gets added from the highest order table. Logicals with
multiple equivalence names are mapped to a variable with multiple
values separated by a comma (,).
HashMap logicals = new HashMap();
String logName = null, logValue = null, newLogName;
String line = null;
while ((line = in.readLine()) != null) {
// parse the VMS logicals into required format ("VAR=VAL[,VAL2]")
if (line.startsWith("\t=")) {
// further equivalence name of previous logical
if (logName != null) {
logValue += "," + line.substring(4, line.length() - 1);
}
} else if (line.startsWith(" \"")) {
// new logical?
if (logName != null) {
logicals.put(logName, logValue);
}
int eqIndex = line.indexOf('=");
newLogName = line.substring(3, eqIndex - 2);
if (logicals.containsKey(newLogName)) {
// already got this logical from a higher order table
logName = null;
} else {
logName = newLogName;
logValue = line.substring(eqIndex + 3, line.length() - 1);
}
}
}
// Since we "look ahead" before adding, there's one last env var.
if (logName != null) {
logicals.put(logName, logValue);
}
for (Iterator i = logicals.keySet().iterator(); i.hasNext();) {
String logical = (String) i.next();
environment.add(logical + "=" + logicals.get(logical));
}
return environment;
|
public static void | closeStreams(java.lang.Process process)Close the streams belonging to the given Process.
FileUtils.close(process.getInputStream());
FileUtils.close(process.getOutputStream());
FileUtils.close(process.getErrorStream());
|
public int | execute()Runs a process defined by the command line and returns its exit status.
if (workingDirectory != null && !workingDirectory.exists()) {
throw new BuildException(workingDirectory + " doesn't exist.");
}
final Process process = launch(project, getCommandline(),
getEnvironment(), workingDirectory,
useVMLauncher);
try {
streamHandler.setProcessInputStream(process.getOutputStream());
streamHandler.setProcessOutputStream(process.getInputStream());
streamHandler.setProcessErrorStream(process.getErrorStream());
} catch (IOException e) {
process.destroy();
throw e;
}
streamHandler.start();
try {
// add the process to the list of those to destroy if the VM exits
//
processDestroyer.add(process);
if (watchdog != null) {
watchdog.start(process);
}
waitFor(process);
if (watchdog != null) {
watchdog.stop();
}
streamHandler.stop();
closeStreams(process);
if (watchdog != null) {
watchdog.checkException();
}
return getExitValue();
} catch (ThreadDeath t) {
// #31928: forcibly kill it before continuing.
process.destroy();
throw t;
} finally {
// remove the process to the list of those to destroy if
// the VM exits
//
processDestroyer.remove(process);
}
|
public java.lang.String[] | getCommandline()Returns the commandline used to create a subprocess.
return cmdl;
|
public java.lang.String[] | getEnvironment()Returns the environment used to create a subprocess.
return (env == null || newEnvironment)
? env : patchEnvironment();
|
public int | getExitValue()Query the exit value of the process.
return exitValue;
|
private static java.lang.String[] | getProcEnvCommand()This is the operation to get our environment.
It is a notorious troublespot pre-Java1.5, and should be approached
with extreme caution.
if (Os.isFamily("os/2")) {
// OS/2 - use same mechanism as Windows 2000
return new String[] {"cmd", "/c", "set" };
} else if (Os.isFamily("windows")) {
// Determine if we're running under XP/2000/NT or 98/95
if (Os.isFamily("win9x")) {
// Windows 98/95
return new String[] {"command.com", "/c", "set" };
} else {
// Windows XP/2000/NT/2003
return new String[] {"cmd", "/c", "set" };
}
} else if (Os.isFamily("z/os") || Os.isFamily("unix")) {
// On most systems one could use: /bin/sh -c env
// Some systems have /bin/env, others /usr/bin/env, just try
String[] cmd = new String[1];
if (new File("/bin/env").canRead()) {
cmd[0] = "/bin/env";
} else if (new File("/usr/bin/env").canRead()) {
cmd[0] = "/usr/bin/env";
} else {
// rely on PATH
cmd[0] = "env";
}
return cmd;
} else if (Os.isFamily("netware") || Os.isFamily("os/400")) {
// rely on PATH
return new String[] {"env"};
} else if (Os.isFamily("openvms")) {
return new String[] {"show", "logical"};
} else {
// MAC OS 9 and previous
//TODO: I have no idea how to get it, someone must fix it
return null;
}
|
public static synchronized java.util.Vector | getProcEnvironment()Find the list of environment variables for this process.
if (procEnvironment != null) {
return procEnvironment;
}
procEnvironment = new Vector();
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Execute exe = new Execute(new PumpStreamHandler(out));
exe.setCommandline(getProcEnvCommand());
// Make sure we do not recurse forever
exe.setNewenvironment(true);
int retval = exe.execute();
if (retval != 0) {
// Just try to use what we got
}
BufferedReader in =
new BufferedReader(new StringReader(toString(out)));
if (Os.isFamily("openvms")) {
procEnvironment = addVMSLogicals(procEnvironment, in);
return procEnvironment;
}
String var = null;
String line, lineSep = StringUtils.LINE_SEP;
while ((line = in.readLine()) != null) {
if (line.indexOf('=") == -1) {
// Chunk part of previous env var (UNIX env vars can
// contain embedded new lines).
if (var == null) {
var = lineSep + line;
} else {
var += lineSep + line;
}
} else {
// New env var...append the previous one if we have it.
if (var != null) {
procEnvironment.addElement(var);
}
var = line;
}
}
// Since we "look ahead" before adding, there's one last env var.
if (var != null) {
procEnvironment.addElement(var);
}
} catch (java.io.IOException exc) {
exc.printStackTrace();
// Just try to see how much we got
}
return procEnvironment;
|
public java.io.File | getWorkingDirectory()Return the working directory.
return workingDirectory == null ? new File(antWorkingDirectory)
: workingDirectory;
|
public static boolean | isFailure(int exitValue)Checks whether exitValue signals a failure on the current
system (OS specific).
Note that this method relies on the conventions of
the OS, it will return false results if the application you are
running doesn't follow these conventions. One notable
exception is the Java VM provided by HP for OpenVMS - it will
return 0 if successful (like on any other platform), but this
signals a failure on OpenVMS. So if you execute a new Java VM
on OpenVMS, you cannot trust this method.
//on openvms even exit value signals failure;
// for other platforms nonzero exit value signals failure
return Os.isFamily("openvms")
? (exitValue % 2 == 0) : (exitValue != 0);
|
public boolean | isFailure()Did this execute return in a failure.
return isFailure(getExitValue());
|
public boolean | killedProcess()Test for an untimely death of the process.
return watchdog != null && watchdog.killedProcess();
|
public static java.lang.Process | launch(org.apache.tools.ant.Project project, java.lang.String[] command, java.lang.String[] env, java.io.File dir, boolean useVM)Creates a process that runs a command.
if (dir != null && !dir.exists()) {
throw new BuildException(dir + " doesn't exist.");
}
CommandLauncher launcher
= ((useVM && vmLauncher != null) ? vmLauncher : shellLauncher);
return launcher.exec(project, command, env, dir);
|
private java.lang.String[] | patchEnvironment()Patch the current environment with the new values from the user.
// On OpenVMS Runtime#exec() doesn't support the environment array,
// so we only return the new values which then will be set in
// the generated DCL script, inheriting the parent process environment
if (Os.isFamily("openvms")) {
return env;
}
Vector osEnv = (Vector) getProcEnvironment().clone();
for (int i = 0; i < env.length; i++) {
String keyValue = env[i];
// Get key including "="
String key = keyValue.substring(0, keyValue.indexOf('=") + 1);
if (environmentCaseInSensitive) {
// Nb: using default locale as key is a env name
key = key.toLowerCase();
}
int size = osEnv.size();
// Find the key in the current enviroment copy
// and remove it.
for (int j = 0; j < size; j++) {
String osEnvItem = (String) osEnv.elementAt(j);
String convertedItem = environmentCaseInSensitive
? osEnvItem.toLowerCase() : osEnvItem;
if (convertedItem.startsWith(key)) {
osEnv.removeElementAt(j);
if (environmentCaseInSensitive) {
// Use the original casiness of the key
keyValue = osEnvItem.substring(0, key.length())
+ keyValue.substring(key.length());
}
break;
}
}
// Add the key to the enviromnent copy
osEnv.addElement(keyValue);
}
return (String[]) (osEnv.toArray(new String[osEnv.size()]));
|
public static void | runCommand(org.apache.tools.ant.Task task, java.lang.String[] cmdline)A utility method that runs an external command. Writes the output and
error streams of the command to the project log.
try {
task.log(Commandline.describeCommand(cmdline),
Project.MSG_VERBOSE);
Execute exe = new Execute(
new LogStreamHandler(task, Project.MSG_INFO, Project.MSG_ERR));
exe.setAntRun(task.getProject());
exe.setCommandline(cmdline);
int retval = exe.execute();
if (isFailure(retval)) {
throw new BuildException(cmdline[0]
+ " failed with return code " + retval, task.getLocation());
}
} catch (java.io.IOException exc) {
throw new BuildException("Could not launch " + cmdline[0] + ": "
+ exc, task.getLocation());
}
|
public void | setAntRun(org.apache.tools.ant.Project project)Set the name of the antRun script using the project's value.
this.project = project;
|
public void | setCommandline(java.lang.String[] commandline)Sets the commandline of the subprocess to launch.
cmdl = commandline;
|
public void | setEnvironment(java.lang.String[] env)Sets the environment variables for the subprocess to launch.
this.env = env;
|
protected void | setExitValue(int value)Set the exit value.
exitValue = value;
|
public void | setNewenvironment(boolean newenv)Set whether to propagate the default environment or not.
newEnvironment = newenv;
|
public void | setSpawn(boolean spawn)Set whether or not you want the process to be spawned.
Default is not spawned.
/*
* Builds a command launcher for the OS and JVM we are running under.
*/
// Try using a JDK 1.3 launcher
try {
if (!Os.isFamily("os/2")) {
vmLauncher = new Java13CommandLauncher();
}
} catch (NoSuchMethodException exc) {
// Ignore and keep trying
}
if (Os.isFamily("mac") && !Os.isFamily("unix")) {
// Mac
shellLauncher = new MacCommandLauncher(new CommandLauncher());
} else if (Os.isFamily("os/2")) {
// OS/2
shellLauncher = new OS2CommandLauncher(new CommandLauncher());
} else if (Os.isFamily("windows")) {
environmentCaseInSensitive = true;
CommandLauncher baseLauncher = new CommandLauncher();
if (!Os.isFamily("win9x")) {
// Windows XP/2000/NT
shellLauncher = new WinNTCommandLauncher(baseLauncher);
} else {
// Windows 98/95 - need to use an auxiliary script
shellLauncher
= new ScriptCommandLauncher("bin/antRun.bat", baseLauncher);
}
} else if (Os.isFamily("netware")) {
CommandLauncher baseLauncher = new CommandLauncher();
shellLauncher
= new PerlScriptCommandLauncher("bin/antRun.pl", baseLauncher);
} else if (Os.isFamily("openvms")) {
// OpenVMS
try {
shellLauncher = new VmsCommandLauncher();
} catch (NoSuchMethodException exc) {
// Ignore and keep trying
}
} else {
// Generic
shellLauncher = new ScriptCommandLauncher("bin/antRun",
new CommandLauncher());
}
this.spawn = spawn;
|
public void | setStreamHandler(ExecuteStreamHandler streamHandler)Set the stream handler to use.
this.streamHandler = streamHandler;
|
public void | setVMLauncher(boolean useVMLauncher)Launch this execution through the VM, where possible, rather than through
the OS's shell. In some cases and operating systems using the shell will
allow the shell to perform additional processing such as associating an
executable with a script, etc.
this.useVMLauncher = useVMLauncher;
|
public void | setWorkingDirectory(java.io.File wd)Sets the working directory of the process to execute.
This is emulated using the antRun scripts unless the OS is
Windows NT in which case a cmd.exe is spawned,
or MRJ and setting user.dir works, or JDK 1.3 and there is
official support in java.lang.Runtime.
workingDirectory =
(wd == null || wd.getAbsolutePath().equals(antWorkingDirectory))
? null : wd;
|
public void | spawn()Starts a process defined by the command line.
Ant will not wait for this process, nor log its output.
if (workingDirectory != null && !workingDirectory.exists()) {
throw new BuildException(workingDirectory + " doesn't exist.");
}
final Process process = launch(project, getCommandline(),
getEnvironment(), workingDirectory,
useVMLauncher);
if (Os.isFamily("windows")) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
project.log("interruption in the sleep after having spawned a"
+ " process", Project.MSG_VERBOSE);
}
}
OutputStream dummyOut = new OutputStream() {
public void write(int b) throws IOException {
}
};
ExecuteStreamHandler handler = new PumpStreamHandler(dummyOut);
handler.setProcessErrorStream(process.getErrorStream());
handler.setProcessOutputStream(process.getInputStream());
handler.start();
process.getOutputStream().close();
project.log("spawned process " + process.toString(),
Project.MSG_VERBOSE);
|
public static java.lang.String | toString(java.io.ByteArrayOutputStream bos)ByteArrayOutputStream#toString doesn't seem to work reliably on
OS/390, at least not the way we use it in the execution
context.
if (Os.isFamily("z/os")) {
try {
return bos.toString("Cp1047");
} catch (java.io.UnsupportedEncodingException e) {
//noop default encoding used
}
} else if (Os.isFamily("os/400")) {
try {
return bos.toString("Cp500");
} catch (java.io.UnsupportedEncodingException e) {
//noop default encoding used
}
}
return bos.toString();
|
protected void | waitFor(java.lang.Process process)Wait for a given process.
try {
process.waitFor();
setExitValue(process.exitValue());
} catch (InterruptedException e) {
process.destroy();
}
|