📄 execute.java
字号:
/* * 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;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.OutputStream;import java.io.PrintWriter;import java.io.StringReader;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Iterator;import java.util.Vector;import org.apache.tools.ant.BuildException;import org.apache.tools.ant.MagicNames;import org.apache.tools.ant.Project;import org.apache.tools.ant.Task;import org.apache.tools.ant.taskdefs.condition.Os;import org.apache.tools.ant.types.Commandline;import org.apache.tools.ant.util.FileUtils;import org.apache.tools.ant.util.StringUtils;/** * Runs an external program. * * @since Ant 1.2 * */public class Execute { private static final int ONE_SECOND = 1000; /** Invalid exit code. * set to {@link Integer#MAX_VALUE} */ public static final int INVALID = Integer.MAX_VALUE; private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); private String[] cmdl = null; private String[] env = null; private int exitValue = INVALID; private ExecuteStreamHandler streamHandler; private ExecuteWatchdog watchdog; private File workingDirectory = null; private Project project = null; private boolean newEnvironment = false; //TODO: nothing appears to read this but is set using a public setter. private boolean spawn = false; /** Controls whether the VM is used to launch commands, where possible. */ private boolean useVMLauncher = true; private static String antWorkingDirectory = System.getProperty("user.dir"); private static CommandLauncher vmLauncher = null; private static CommandLauncher shellLauncher = null; private static Vector procEnvironment = null; /** Used to destroy processes when the VM exits. */ private static ProcessDestroyer processDestroyer = new ProcessDestroyer(); /** Used for replacing env variables */ private static boolean environmentCaseInSensitive = false; /* * Builds a command launcher for the OS and JVM we are running under. */ static { // Try using a JDK 1.3 launcher try { if (!Os.isFamily("os/2")) { vmLauncher = new Java13CommandLauncher(); } } catch (NoSuchMethodException exc) { // Ignore and keep trying } if (Os.isFamily("mac") && !Os.isFamily("unix")) { // Mac shellLauncher = new MacCommandLauncher(new CommandLauncher()); } else if (Os.isFamily("os/2")) { // OS/2 shellLauncher = new OS2CommandLauncher(new CommandLauncher()); } else if (Os.isFamily("windows")) { environmentCaseInSensitive = true; CommandLauncher baseLauncher = new CommandLauncher(); if (!Os.isFamily("win9x")) { // Windows XP/2000/NT shellLauncher = new WinNTCommandLauncher(baseLauncher); } else { // Windows 98/95 - need to use an auxiliary script shellLauncher = new ScriptCommandLauncher("bin/antRun.bat", baseLauncher); } } else if (Os.isFamily("netware")) { CommandLauncher baseLauncher = new CommandLauncher(); shellLauncher = new PerlScriptCommandLauncher("bin/antRun.pl", baseLauncher); } else if (Os.isFamily("openvms")) { // OpenVMS try { shellLauncher = new VmsCommandLauncher(); } catch (NoSuchMethodException exc) { // Ignore and keep trying } } else { // Generic shellLauncher = new ScriptCommandLauncher("bin/antRun", new CommandLauncher()); } } /** * Set whether or not you want the process to be spawned. * Default is not spawned. * * @param spawn if true you do not want Ant * to wait for the end of the process. * * @since Ant 1.6 */ public void setSpawn(boolean spawn) { this.spawn = spawn; } /** * Find the list of environment variables for this process. * * @return a vector containing the environment variables. * The vector elements are strings formatted like variable = value. */ public static synchronized Vector getProcEnvironment() { if (procEnvironment != null) { return procEnvironment; } procEnvironment = new Vector(); try { ByteArrayOutputStream out = new ByteArrayOutputStream(); Execute exe = new Execute(new PumpStreamHandler(out)); exe.setCommandline(getProcEnvCommand()); // Make sure we do not recurse forever exe.setNewenvironment(true); int retval = exe.execute(); if (retval != 0) { // Just try to use what we got } BufferedReader in = new BufferedReader(new StringReader(toString(out))); if (Os.isFamily("openvms")) { procEnvironment = addVMSLogicals(procEnvironment, in); return procEnvironment; } String var = null; String line, lineSep = StringUtils.LINE_SEP; while ((line = in.readLine()) != null) { if (line.indexOf('=') == -1) { // Chunk part of previous env var (UNIX env vars can // contain embedded new lines). if (var == null) { var = lineSep + line; } else { var += lineSep + line; } } else { // New env var...append the previous one if we have it. if (var != null) { procEnvironment.addElement(var); } var = line; } } // Since we "look ahead" before adding, there's one last env var. if (var != null) { procEnvironment.addElement(var); } } catch (java.io.IOException exc) { exc.printStackTrace(); // Just try to see how much we got } return procEnvironment; } /** * This is the operation to get our environment. * It is a notorious troublespot pre-Java1.5, and should be approached * with extreme caution. * @return */ private static String[] getProcEnvCommand() { if (Os.isFamily("os/2")) { // OS/2 - use same mechanism as Windows 2000 return new String[] {"cmd", "/c", "set" }; } else if (Os.isFamily("windows")) { // Determine if we're running under XP/2000/NT or 98/95 if (Os.isFamily("win9x")) { // Windows 98/95 return new String[] {"command.com", "/c", "set" }; } else { // Windows XP/2000/NT/2003 return new String[] {"cmd", "/c", "set" }; } } else if (Os.isFamily("z/os") || Os.isFamily("unix")) { // On most systems one could use: /bin/sh -c env // Some systems have /bin/env, others /usr/bin/env, just try String[] cmd = new String[1]; if (new File("/bin/env").canRead()) { cmd[0] = "/bin/env"; } else if (new File("/usr/bin/env").canRead()) { cmd[0] = "/usr/bin/env"; } else { // rely on PATH cmd[0] = "env"; } return cmd; } else if (Os.isFamily("netware") || Os.isFamily("os/400")) { // rely on PATH return new String[] {"env"}; } else if (Os.isFamily("openvms")) { return new String[] {"show", "logical"}; } else { // MAC OS 9 and previous //TODO: I have no idea how to get it, someone must fix it return null; } } /** * ByteArrayOutputStream#toString doesn't seem to work reliably on * OS/390, at least not the way we use it in the execution * context. * * @param bos the output stream that one wants to read. * @return the output stream as a string, read with * special encodings in the case of z/os and os/400. * * @since Ant 1.5 */ public static String toString(ByteArrayOutputStream bos) { if (Os.isFamily("z/os")) { try { return bos.toString("Cp1047"); } catch (java.io.UnsupportedEncodingException e) { //noop default encoding used } } else if (Os.isFamily("os/400")) { try { return bos.toString("Cp500"); } catch (java.io.UnsupportedEncodingException e) { //noop default encoding used } } return bos.toString(); } /** * Creates a new execute object using <code>PumpStreamHandler</code> for * stream handling. */ public Execute() { this(new PumpStreamHandler(), null); } /** * Creates a new execute object. * * @param streamHandler the stream handler used to handle the input and * output streams of the subprocess. */ public Execute(ExecuteStreamHandler streamHandler) { this(streamHandler, null); } /** * Creates a new execute object. * * @param streamHandler the stream handler used to handle the input and * output streams of the subprocess. * @param watchdog a watchdog for the subprocess or <code>null</code> to * to disable a timeout for the subprocess. */ public Execute(ExecuteStreamHandler streamHandler, ExecuteWatchdog watchdog) { setStreamHandler(streamHandler); this.watchdog = watchdog;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -