Browse Source

improved OpenVMS support, submitted by Knut Wannheden <knut dot wannheden at paranor dot ch>

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275346 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 21 years ago
parent
commit
655ad8f525
4 changed files with 110 additions and 15 deletions
  1. +14
    -7
      docs/manual/CoreTasks/exec.html
  2. +4
    -1
      src/main/org/apache/tools/ant/DirectoryScanner.java
  3. +31
    -7
      src/main/org/apache/tools/ant/taskdefs/Execute.java
  4. +61
    -0
      src/main/org/apache/tools/ant/util/FileUtils.java

+ 14
- 7
docs/manual/CoreTasks/exec.html View File

@@ -20,20 +20,27 @@ Windows executable and is not aware of Cygwin conventions.
</p> </p>
<h4>OpenVMS Users</h4> <h4>OpenVMS Users</h4>

<p>The command specified using <code>executable</code> and <p>The command specified using <code>executable</code> and
<code>&lt;arg&gt;</code> elements is executed exactly as specified <code>&lt;arg&gt;</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>
inside a temporary DCL script. This has some implications:
<ul>
<li>paths have to be written in VMS style</li>
<li>if your <code>executable</code> points to a DCL script remember to
prefix it with an <code>@</code>-sign
(e.g. <code>executable="@[FOO]BAR.COM"</code>), just as you would in a
DCL script</li>
</ul>
For <code>&lt;exec&gt;</code> to work in an environment with a Java VM
older than version 1.4.1-2 it is also <i>required</i> that the logical
<code>JAVA$FORK_SUPPORT_CHDIR</code> is set to <code>TRUE</code> in
the job table (see the <i>JDK Release Notes</i>).</p>

<p>Please note that the Java VM provided by HP doesn't follow OpenVMS' <p>Please note that the Java VM provided by HP doesn't follow OpenVMS'
conventions of exit codes. If you run a Java VM with this task, the conventions of exit codes. If you run a Java VM with this task, the
task may falsely claim that an error occured (or silently ignore an task may falsely claim that an error occured (or silently ignore an
error). Don't use this task to run <code>JAVA.EXE</code>, use a error). Don't use this task to run <code>JAVA.EXE</code>, use a
<code>&lt;java&gt;</code> task with the <code>fork</code> attribute <code>&lt;java&gt;</code> task with the <code>fork</code> attribute
set ti <code>true</code> instead as this task will follow the VM's
set to <code>true</code> instead as this task will follow the VM's
interpretation of exit codes.</p> interpretation of exit codes.</p>


<h3>Parameters</h3> <h3>Parameters</h3>


+ 4
- 1
src/main/org/apache/tools/ant/DirectoryScanner.java View File

@@ -65,6 +65,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Vector; import java.util.Vector;


import org.apache.tools.ant.taskdefs.condition.Os;
import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceFactory; import org.apache.tools.ant.types.ResourceFactory;
import org.apache.tools.ant.types.selectors.FileSelector; import org.apache.tools.ant.types.selectors.FileSelector;
@@ -163,6 +164,8 @@ import org.apache.tools.ant.util.FileUtils;
public class DirectoryScanner public class DirectoryScanner
implements FileScanner, SelectorScanner, ResourceFactory { implements FileScanner, SelectorScanner, ResourceFactory {


/** Is OpenVMS the operating system we're running on? */
private static final boolean ON_VMS = Os.isFamily("openvms");


/** /**
* Patterns which should be excluded by default. * Patterns which should be excluded by default.
@@ -725,7 +728,7 @@ public class DirectoryScanner
File canonFile = myfile.getCanonicalFile(); File canonFile = myfile.getCanonicalFile();
String path = fileUtils.removeLeadingPath(canonBase, String path = fileUtils.removeLeadingPath(canonBase,
canonFile); canonFile);
if (!path.equals(currentelement)) {
if (!path.equals(currentelement) || ON_VMS) {
myfile = findFile(basedir, currentelement); myfile = findFile(basedir, currentelement);
if (myfile != null) { if (myfile != null) {
currentelement = currentelement =


+ 31
- 7
src/main/org/apache/tools/ant/taskdefs/Execute.java View File

@@ -621,6 +621,13 @@ public class Execute {
* @return the patched environment * @return the patched environment
*/ */
private String[] patchEnvironment() { private String[] patchEnvironment() {
// 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(); Vector osEnv = (Vector) getProcEnvironment().clone();
for (int i = 0; i < env.length; i++) { for (int i = 0; i < env.length; i++) {
int pos = env[i].indexOf('='); int pos = env[i].indexOf('=');
@@ -1119,7 +1126,7 @@ public class Execute {
*/ */
public Process exec(Project project, String[] cmd, String[] env) public Process exec(Project project, String[] cmd, String[] env)
throws IOException { throws IOException {
String[] vmsCmd = {createCommandFile(cmd).getPath()};
String[] vmsCmd = {createCommandFile(cmd, env).getPath()};
return super.exec(project, vmsCmd, env); return super.exec(project, vmsCmd, env);
} }


@@ -1131,7 +1138,7 @@ public class Execute {
*/ */
public Process exec(Project project, String[] cmd, String[] env, public Process exec(Project project, String[] cmd, String[] env,
File workingDir) throws IOException { File workingDir) throws IOException {
String[] vmsCmd = {createCommandFile(cmd).getPath()};
String[] vmsCmd = {createCommandFile(cmd, env).getPath()};
return super.exec(project, vmsCmd, env, workingDir); return super.exec(project, vmsCmd, env, workingDir);
} }


@@ -1139,17 +1146,34 @@ public class Execute {
* Writes the command into a temporary DCL script and returns the * Writes the command into a temporary DCL script and returns the
* corresponding File object. The script will be deleted on exit. * corresponding File object. The script will be deleted on exit.
*/ */
private File createCommandFile(String[] cmd) throws IOException {
private File createCommandFile(String[] cmd, String[] env)
throws IOException {
File script = File.createTempFile("ANT", ".COM"); File script = File.createTempFile("ANT", ".COM");
script.deleteOnExit(); script.deleteOnExit();
PrintWriter out = null; PrintWriter out = null;
try { try {
out = new PrintWriter(new FileWriter(script)); out = new PrintWriter(new FileWriter(script));
StringBuffer dclCmd = new StringBuffer("$");
for (int i = 0; i < cmd.length; i++) {
dclCmd.append(' ').append(cmd[i]);

// add the environment as logicals to the DCL script
if (env != null) {
int eqIndex;
for (int i = 1; i < env.length ; i++) {
eqIndex = env[i].indexOf('=');
if (eqIndex != -1) {
out.print("$ DEFINE/NOLOG ");
out.print(env[i].substring(0, eqIndex));
out.print(" \"");
out.print(env[i].substring(eqIndex + 1));
out.println('\"');
}
}
}

out.print("$ " + cmd[0]);
for (int i = 1; i < cmd.length ; i++) {
out.println(" -");
out.print(cmd[i]);
} }
out.println(dclCmd.toString());
} finally { } finally {
if (out != null) { if (out != null) {
out.close(); out.close();


+ 61
- 0
src/main/org/apache/tools/ant/util/FileUtils.java View File

@@ -824,6 +824,8 @@ public class FileUtils {
* <li>DOS style paths that start with a drive letter will have * <li>DOS style paths that start with a drive letter will have
* \ as the separator.</li> * \ as the separator.</li>
* </ul> * </ul>
* Unlike <code>File#getCanonicalPath()</code> it specifically doesn't
* resolve symbolic links.
* *
* @param path the path to be normalized * @param path the path to be normalized
* @return the normalized version of the path. * @return the normalized version of the path.
@@ -937,6 +939,65 @@ public class FileUtils {
return new File(path); return new File(path);
} }


/**
* Returns a VMS String representation of a <code>File</code> object.
* This is useful since the JVM by default internally converts VMS paths
* to Unix style.
* The returned String is always an absolute path.
*
* @param f The <code>File</code> to get the VMS path for.
* @return The absolute VMS path to <code>f</code>.
*/
public String toVMSPath(File f) {
// format: "DEVICE:[DIR.SUBDIR]FILE"
String osPath;
String path = normalize(f.getAbsolutePath()).getPath();
String name = f.getName();
boolean isAbsolute = path.charAt(0) == File.separatorChar;
// treat directories specified using .DIR syntax as files
boolean isDirectory = f.isDirectory() &&
!name.regionMatches(true, name.length() - 4, ".DIR", 0, 4);

String device = null;
StringBuffer directory = null;
String file = null;

int index = 0;

if (isAbsolute) {
index = path.indexOf(File.separatorChar, 1);
if (index == -1) {
return path.substring(1) + ":[000000]";
} else {
device = path.substring(1, index++);
}
}
if (isDirectory) {
directory = new StringBuffer(path.substring(index).
replace(File.separatorChar, '.'));
} else {
int dirEnd =
path.lastIndexOf(File.separatorChar, path.length());
if (dirEnd == -1 || dirEnd < index) {
file = path.substring(index);
} else {
directory = new StringBuffer(path.substring(index, dirEnd).
replace(File.separatorChar, '.'));
index = dirEnd + 1;
if (path.length() > index) {
file = path.substring(index);
}
}
}
if (!isAbsolute && directory != null) {
directory.insert(0, '.');
}
osPath = ((device != null) ? device + ":" : "") +
((directory != null) ? "[" + directory + "]" : "") +
((file != null) ? file : "");
return osPath;
}

/** /**
* Create a temporary file in a given directory. * Create a temporary file in a given directory.
* *


Loading…
Cancel
Save