bodewig 2003/07/25 03:06:32 Modified: . WHATSNEW docs/manual/CoreTasks exec.html src/main/org/apache/tools/ant/taskdefs ExecTask.java Execute.java Log: Add OpenVMS support to <exec>. PR: 21877 Submitted by: Knut Wannheden <knut at paranor dot ch> Revision Changes Path 1.467 +3 -0 ant/WHATSNEW Index: WHATSNEW =================================================================== RCS file: /home/cvs/ant/WHATSNEW,v retrieving revision 1.466 retrieving revision 1.467 diff -u -r1.466 -r1.467 --- WHATSNEW 24 Jul 2003 13:19:26 -0000 1.466 +++ WHATSNEW 25 Jul 2003 10:06:31 -0000 1.467 @@ -513,6 +513,9 @@ mappings per source path. This behaviour is enabled by using an enablemultiplemapping attribute. Bugzilla Report 21320. +* <exec> will now work on OpenVMS (please read the notes in + <exec>'s manual page). Bugzilla Report 21877. + Changes from Ant 1.5.2 to Ant 1.5.3 =================================== 1.27 +16 -8 ant/docs/manual/CoreTasks/exec.html Index: exec.html =================================================================== RCS file: /home/cvs/ant/docs/manual/CoreTasks/exec.html,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- exec.html 24 Feb 2003 14:39:23 -0000 1.26 +++ exec.html 25 Jul 2003 10:06:31 -0000 1.27 @@ -19,6 +19,14 @@ Windows executable and is not aware of Cygwin conventions. </p> +<h4>OpenVMS Users</h4> +<p>The command specified using <code>executable</code> and <code><arg></code> +elements is executed exactly as specified inside a temporary DCL script. This means +that paths have to be written in VMS style. It is also required that the logical +<code>JAVA$FORK_SUPPORT_CHDIR</code> is set to <code>TRUE</code> (see the <i>JDK Release +Notes</i>). +</p> + <h3>Parameters</h3> <table border="1" cellpadding="2" cellspacing="0"> <tr> @@ -108,7 +116,7 @@ <tr> <td valign="top">resultproperty</td> <td valign="top">the name of a property in which the return code of the - command should be stored. Only of interest if failonerror=false</td> + command should be stored. Only of interest if failonerror=false.</td> <td align="center" valign="top">No</td> </tr> <tr> @@ -120,7 +128,7 @@ <tr> <td valign="top">failonerror</td> <td valign="top">Stop the buildprocess if the command exits with a - returncode other than 0. Defaults to false</td> + return code signaling failure. Defaults to false.</td> <td align="center" valign="top">No</td> </tr> <tr> @@ -204,15 +212,15 @@ <h3>Errors and return codes</h3> By default the return code of a <exec> is ignored; when you set -<code>failonerror="true"</code> then any non zero response is treated as an -error. Alternatively, you can set <code>resultproperty</code> to the name -of a property and have it assigned to the result code (barring immutability, -of course). +<code>failonerror="true"</code> then any return code signaling failure +(OS specific) causes the build to fail. Alternatively, you can set +<code>resultproperty</code> to the name of a property and have it assigned to +the result code (barring immutability, of course). <p> If the attempt to start the program fails with an OS dependent error code, then <exec> halts the build unless <code>failifexecutionfails</code> -is set. You can use that to run a program if it exists, but otherwise -do nothing. +is set to <code>false</code>. You can use that to run a program if it exists, but +otherwise do nothing. <p> What do those error codes mean? Well, they are OS dependent. On Windows boxes you have to look in include\error.h in your windows compiler or wine files; 1.56 +1 -1 ant/src/main/org/apache/tools/ant/taskdefs/ExecTask.java Index: ExecTask.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/ExecTask.java,v retrieving revision 1.55 retrieving revision 1.56 diff -u -r1.55 -r1.56 --- ExecTask.java 19 Jul 2003 08:10:59 -0000 1.55 +++ ExecTask.java 25 Jul 2003 10:06:31 -0000 1.56 @@ -413,7 +413,7 @@ log("Timeout: killed the sub-process", Project.MSG_WARN); } maybeSetResultPropertyValue(returnCode); - if (returnCode != 0) { + if (Execute.isFailure(returnCode)) { if (failOnError) { throw new BuildException(getTaskType() + " returned: " + returnCode, getLocation()); 1.58 +87 -4 ant/src/main/org/apache/tools/ant/taskdefs/Execute.java Index: Execute.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Execute.java,v retrieving revision 1.57 retrieving revision 1.58 diff -u -r1.57 -r1.58 --- Execute.java 19 Jul 2003 08:10:59 -0000 1.57 +++ Execute.java 25 Jul 2003 10:06:32 -0000 1.58 @@ -57,7 +57,9 @@ import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileWriter; import java.io.IOException; +import java.io.PrintWriter; import java.io.StringReader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -109,7 +111,9 @@ static { // Try using a JDK 1.3 launcher try { - if (!Os.isFamily("os/2")) { + if (Os.isFamily("openvms")) { + vmLauncher = new VmsCommandLauncher(); + } else if (!Os.isFamily("os/2")) { vmLauncher = new Java13CommandLauncher(); } } catch (NoSuchMethodException exc) { @@ -155,6 +159,9 @@ shellLauncher = new PerlScriptCommandLauncher("bin/antRun.pl", baseLauncher); + } else if (Os.isFamily("openvms")) { + // the vmLauncher already uses the shell + shellLauncher = vmLauncher; } else { // Generic shellLauncher = new ScriptCommandLauncher("bin/antRun", @@ -249,6 +256,9 @@ // rely on PATH String[] cmd = {"env"}; return cmd; + } else if (Os.isFamily("openvms")) { + String[] cmd = {"show", "logical"}; + return cmd; } else { // MAC OS 9 and previous // TODO: I have no idea how to get it, someone must fix it @@ -490,15 +500,31 @@ } /** - * query the exit value of the process. + * Query the exit value of the process. * @return the exit value, 1 if the process was killed, - * or Project.INVALID if no exit value has been received + * or Execute.INVALID if no exit value has been received */ public int getExitValue() { return exitValue; } /** + * Checks whether <code>exitValue</code> signals a failure on the current + * system (OS specific). + * @param exitValue the exit value (return code) to be checked + * @return <code>true</code> if <code>exitValue</code> signals a failure + */ + public static boolean isFailure(int exitValue) { + if (Os.isFamily("openvms")) { + // odd exit value signals failure + return (exitValue % 2) == 0; + } else { + // non zero exit value signals failure + return exitValue != 0; + } + } + + /** * test for an untimely death of the process * @return true iff a watchdog had to kill the process * @since Ant 1.5 @@ -911,5 +937,62 @@ } private String _script; + } + + /** + * A command launcher for VMS that writes the command to a temporary DCL + * script before launching commands. This is due to limitations of both + * the DCL interpreter and the Java VM implementation. + */ + private static class VmsCommandLauncher extends Java13CommandLauncher { + + public VmsCommandLauncher() throws NoSuchMethodException { + super(); + } + + /** + * Launches the given command in a new process. + */ + public Process exec(Project project, String[] cmd, String[] env) + throws IOException { + String[] vmsCmd = { createCommandFile(cmd).getPath() }; + return super.exec(project, vmsCmd, env); + } + + /** + * Launches the given command in a new process, in the given working + * directory. Note that under Java 1.3.1, 1.4.0 and 1.4.1 on VMS this + * method only works if <code>workingDir</code> is null or the logical + * JAVA$FORK_SUPPORT_CHDIR needs to be set to TRUE. + */ + public Process exec(Project project, String[] cmd, String[] env, + File workingDir) throws IOException { + String[] vmsCmd = { createCommandFile(cmd).getPath() }; + return super.exec(project, vmsCmd, env, workingDir); + } + + /* + * Writes the command into a temporary DCL script and returns the + * corresponding File object. The script will be deleted on exit. + */ + private File createCommandFile(String[] cmd) throws IOException { + File script = File.createTempFile("ANT", ".COM"); + script.deleteOnExit(); + PrintWriter out = null; + try { + out = new PrintWriter(new FileWriter(script)); + StringBuffer dclCmd = new StringBuffer("$"); + for (int i = 0; i < cmd.length; i++) { + dclCmd.append(' ').append(cmd[i]); + } + out.println(dclCmd.toString()); + } finally { + if (out != null) { + out.close(); + } + } + return script; + } + } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]