/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant.taskdefs.launcher; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import org.apache.tools.ant.Project; import org.apache.tools.ant.util.FileUtils; /** * 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. */ public class VmsCommandLauncher extends Java13CommandLauncher { /** * Launches the given command in a new process. * * @param project * the Ant project. * @param cmd * the command line to execute as an array of strings. * @param env * the environment to set as an array of strings. * @return the created Process. * @throws IOException * forwarded from the exec method of the command launcher. */ @Override public Process exec(Project project, String[] cmd, String[] env) throws IOException { File cmdFile = createCommandFile(cmd, env); Process p = super.exec(project, new String[] { cmdFile.getPath() }, env); deleteAfter(cmdFile, p); return p; } /** * Launches the given command in a new process, in the given * working directory. Note that under Java 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. * * @param project * the Ant project. * @param cmd * the command line to execute as an array of strings. * @param env * the environment to set as an array of strings. * @param workingDir * working directory where the command should run. * @return the created Process. * @throws IOException * forwarded from the exec method of the command launcher. */ @Override public Process exec(Project project, String[] cmd, String[] env, File workingDir) throws IOException { File cmdFile = createCommandFile(cmd, env); Process p = super.exec(project, new String[] { cmdFile.getPath() }, env, workingDir); deleteAfter(cmdFile, p); return p; } /* * Writes the command into a temporary DCL script and returns the * corresponding File object. The script will be deleted on exit. * @param cmd the command line to execute as an array of strings. * @param env the environment to set as an array of strings. * @return the command File. * @throws IOException if errors are encountered creating the file. */ private File createCommandFile(String[] cmd, String[] env) throws IOException { File script = FILE_UTILS.createTempFile("ANT", ".COM", null, true, true); try (BufferedWriter out = new BufferedWriter(new FileWriter(script))) { // add the environment as logicals to the DCL script if (env != null) { int eqIndex; for (int i = 0; i < env.length; i++) { eqIndex = env[i].indexOf('='); if (eqIndex != -1) { out.write("$ DEFINE/NOLOG "); out.write(env[i].substring(0, eqIndex)); out.write(" \""); out.write(env[i].substring(eqIndex + 1)); out.write('\"'); out.newLine(); } } } out.write("$ " + cmd[0]); for (int i = 1; i < cmd.length; i++) { out.write(" -"); out.newLine(); out.write(cmd[i]); } } return script; } private void deleteAfter(final File f, final Process p) { new Thread() { @Override public void run() { try { p.waitFor(); } catch(InterruptedException e) { // ignore } FileUtils.delete(f); } }.start(); } }