From 655ad8f525f6d55fe32cbecdd3ef437b0f5d5fa5 Mon Sep 17 00:00:00 2001
From: Stefan Bodewig
Date: Thu, 25 Sep 2003 12:36:19 +0000
Subject: [PATCH] improved OpenVMS support, submitted by Knut Wannheden
git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275346 13f79535-47bb-0310-9956-ffa450edef68
---
docs/manual/CoreTasks/exec.html | 21 ++++---
.../apache/tools/ant/DirectoryScanner.java | 5 +-
.../apache/tools/ant/taskdefs/Execute.java | 38 +++++++++---
.../org/apache/tools/ant/util/FileUtils.java | 61 +++++++++++++++++++
4 files changed, 110 insertions(+), 15 deletions(-)
diff --git a/docs/manual/CoreTasks/exec.html b/docs/manual/CoreTasks/exec.html
index 385b5aec5..50f97f8eb 100644
--- a/docs/manual/CoreTasks/exec.html
+++ b/docs/manual/CoreTasks/exec.html
@@ -20,20 +20,27 @@ Windows executable and is not aware of Cygwin conventions.
OpenVMS Users
-
The command specified using executable
and
<arg>
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
-JAVA$FORK_SUPPORT_CHDIR
is set to TRUE
(see
-the JDK Release Notes).
-
+inside a temporary DCL script. This has some implications:
+
+- paths have to be written in VMS style
+- if your
executable
points to a DCL script remember to
+prefix it with an @
-sign
+(e.g. executable="@[FOO]BAR.COM"
), just as you would in a
+DCL script
+
+For <exec>
to work in an environment with a Java VM
+older than version 1.4.1-2 it is also required that the logical
+JAVA$FORK_SUPPORT_CHDIR
is set to TRUE
in
+the job table (see the JDK Release Notes).
+
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 JAVA.EXE
, use a
<java>
task with the fork
attribute
-set ti true
instead as this task will follow the VM's
+set to true
instead as this task will follow the VM's
interpretation of exit codes.
Parameters
diff --git a/src/main/org/apache/tools/ant/DirectoryScanner.java b/src/main/org/apache/tools/ant/DirectoryScanner.java
index 9b7b1b6e1..d26ffe1f6 100644
--- a/src/main/org/apache/tools/ant/DirectoryScanner.java
+++ b/src/main/org/apache/tools/ant/DirectoryScanner.java
@@ -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 =
diff --git a/src/main/org/apache/tools/ant/taskdefs/Execute.java b/src/main/org/apache/tools/ant/taskdefs/Execute.java
index 44f6e4012..55f7d6a37 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Execute.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Execute.java
@@ -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();
diff --git a/src/main/org/apache/tools/ant/util/FileUtils.java b/src/main/org/apache/tools/ant/util/FileUtils.java
index eada52f11..cc6ae3a06 100644
--- a/src/main/org/apache/tools/ant/util/FileUtils.java
+++ b/src/main/org/apache/tools/ant/util/FileUtils.java
@@ -824,6 +824,8 @@ public class FileUtils {
* DOS style paths that start with a drive letter will have
* \ as the separator.
*
+ * Unlike File#getCanonicalPath()
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 File
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 File
to get the VMS path for.
+ * @return The absolute VMS path to f
.
+ */
+ 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.
*