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>
<h4>OpenVMS Users</h4>

<p>The command specified using <code>executable</code> and
<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'
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
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
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>

<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.Vector;

import org.apache.tools.ant.taskdefs.condition.Os;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceFactory;
import org.apache.tools.ant.types.selectors.FileSelector;
@@ -163,6 +164,8 @@ import org.apache.tools.ant.util.FileUtils;
public class DirectoryScanner
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.
@@ -725,7 +728,7 @@ public class DirectoryScanner
File canonFile = myfile.getCanonicalFile();
String path = fileUtils.removeLeadingPath(canonBase,
canonFile);
if (!path.equals(currentelement)) {
if (!path.equals(currentelement) || ON_VMS) {
myfile = findFile(basedir, currentelement);
if (myfile != null) {
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
*/
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();
for (int i = 0; i < env.length; i++) {
int pos = env[i].indexOf('=');
@@ -1119,7 +1126,7 @@ public class Execute {
*/
public Process exec(Project project, String[] cmd, String[] env)
throws IOException {
String[] vmsCmd = {createCommandFile(cmd).getPath()};
String[] vmsCmd = {createCommandFile(cmd, env).getPath()};
return super.exec(project, vmsCmd, env);
}

@@ -1131,7 +1138,7 @@ public class Execute {
*/
public Process exec(Project project, String[] cmd, String[] env,
File workingDir) throws IOException {
String[] vmsCmd = {createCommandFile(cmd).getPath()};
String[] vmsCmd = {createCommandFile(cmd, env).getPath()};
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
* 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");
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]);

// 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 {
if (out != null) {
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
* \ as the separator.</li>
* </ul>
* Unlike <code>File#getCanonicalPath()</code> it specifically doesn't
* resolve symbolic links.
*
* @param path the path to be normalized
* @return the normalized version of the path.
@@ -937,6 +939,65 @@ public class FileUtils {
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.
*


Loading…
Cancel
Save