Return-Path: Mailing-List: contact ant-dev-help@jakarta.apache.org; run by ezmlm Delivered-To: mailing list ant-dev@jakarta.apache.org Received: (qmail 98689 invoked from network); 8 Aug 2000 20:18:40 -0000 Received: from lukla.sun.com (192.18.98.31) by locus.apache.org with SMTP; 8 Aug 2000 20:18:40 -0000 Received: from gw.netbeans.com ([129.156.76.1]) by lukla.Sun.COM (8.9.3+Sun/8.9.3) with ESMTP id OAA07627 for ; Tue, 8 Aug 2000 14:18:32 -0600 (MDT) Received: from appsrv.netbeans.com (appsrv.netbeans.com [212.24.138.171]) by gw.netbeans.com (8.9.3/8.9.3) with ESMTP id WAA14653 for ; Tue, 8 Aug 2000 22:18:14 +0200 Received: from netbeans.com (IDENT:jglick@karlovo-nb.netbeans.com [212.24.138.185]) by appsrv.netbeans.com (8.9.3/8.9.3) with ESMTP id WAA04556 for ; Tue, 8 Aug 2000 22:18:14 +0200 Sender: Jesse.Glick@netbeans.com Message-ID: <39906B15.4E9CD057@netbeans.com> Date: Tue, 08 Aug 2000 22:18:29 +0200 From: Jesse Glick Organization: Sun Microsystems X-Mailer: Mozilla 4.7 [en] (X11; I; Linux 2.2.12-20 i686) X-Accept-Language: en MIME-Version: 1.0 To: Ant List Subject: [PATCH] make Execute take advantage of 1.3's CWD support Content-Type: multipart/mixed; boundary="------------AA35EAD7C6617A8534E42DA8" X-Spam-Rating: locus.apache.org 1.6.2 0/1000/N This is a multi-part message in MIME format. --------------AA35EAD7C6617A8534E42DA8 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit The attached patch (only lightly tested and only on Linux, please note) should make ExecTask/Execute () take advantage of JDK 1.3's new Runtime.exec accepting a working directory, thus avoiding the need to use antRun. It should also correct a bug in ExecTask that antRun was used even when no 'dir' attribute was given (the working directory did not need to be set at all). And hopefully the code should be a little clearer (all the alternative strategies are listed in order in one method). Previous code had this: private static String antWorkingDirectory = (new File((new File(".")).getAbsolutePath())).getParent(); (Written by Mariusz.) I've replaced that with System.getProperty("user.dir") which is defined from JDK 1.1 to give the intended result, so hopefully the older code was not a workaround for an obscure broken JDK. Two other thoughts about using antRun (not antRun.bat, only the POSIX version): 1. At least on Bash and I thought other Bourne shells, $@ should be "$@" to preserve spaces correctly, I think. (But why <> instead of simply <> or better <>?) 2. If /bin/sh is found to exist at runtime, why not use it rather than rely on some shell script? Take the command array cmdl, then construct a new one of three strings: "/bin/sh", "-c", and then: "cd ${workingDirectory}; " plus each element of cmdl, separated by spaces, surrounded by ticks ('), and properly escaped (' -> '"'"'). Is there something special antRun does beyond this? -Jesse -- Jesse Glick NetBeans, Open APIs tel (+4202) 3300-9161 Sun Micro x49161 Praha CR --------------AA35EAD7C6617A8534E42DA8 Content-Type: text/plain; charset=us-ascii; name="jdk13-cwd-patch.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="jdk13-cwd-patch.diff" Index: docs/index.html =================================================================== RCS file: /home/cvspublic/jakarta-ant/docs/index.html,v retrieving revision 1.67 diff -c -r1.67 index.html *** docs/index.html 2000/08/07 11:47:11 1.67 --- docs/index.html 2000/08/08 19:54:17 *************** *** 1134,1140 **** dir the directory in which the command should be executed. ! Yes os --- 1134,1140 ---- dir the directory in which the command should be executed. ! No os *************** *** 1146,1152 **** output the file to which the output of the command should be redirected. ! Yes failonerror --- 1146,1152 ---- output the file to which the output of the command should be redirected. ! No failonerror Index: src/main/org/apache/tools/ant/taskdefs/ExecTask.java =================================================================== RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecTask.java,v retrieving revision 1.5 diff -c -r1.5 ExecTask.java *** src/main/org/apache/tools/ant/taskdefs/ExecTask.java 2000/08/01 09:18:39 1.5 --- src/main/org/apache/tools/ant/taskdefs/ExecTask.java 2000/08/08 19:54:18 *************** *** 180,187 **** * Create an Execute instance with the correct working directory set. */ protected Execute prepareExec() throws BuildException { - // default directory to the project's base directory - if (dir == null) dir = project.getBaseDir(); // show the command log(cmdl.toString(), Project.MSG_VERBOSE); --- 180,185 ---- Index: src/main/org/apache/tools/ant/taskdefs/Execute.java =================================================================== RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Execute.java,v retrieving revision 1.5 diff -c -r1.5 Execute.java *** src/main/org/apache/tools/ant/taskdefs/Execute.java 2000/08/03 10:29:20 1.5 --- src/main/org/apache/tools/ant/taskdefs/Execute.java 2000/08/08 19:54:18 *************** *** 61,66 **** --- 61,68 ---- import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; + import java.lang.reflect.InvocationTargetException; + import java.lang.reflect.Method; /** *************** *** 78,90 **** private int exitValue = INVALID; private ExecuteStreamHandler streamHandler; private ExecuteWatchdog watchdog; ! private File workingDirectory; private String antRun; ! private static String antWorkingDirectory = ! (new File((new File(".")).getAbsolutePath())).getParent(); private static String myos = System.getProperty("os.name"); /** * Creates a new execute object using PumpStreamHandler for * stream handling. --- 80,102 ---- private int exitValue = INVALID; private ExecuteStreamHandler streamHandler; private ExecuteWatchdog watchdog; ! private File workingDirectory = null; private String antRun; ! private static String antWorkingDirectory = System.getProperty("user.dir"); private static String myos = System.getProperty("os.name"); + private static Method execWithCWD = null; + static { + try { + // JDK 1.3 API extension: + // Runtime.exec(String[] cmdarray, String[] envp, File dir) + execWithCWD = Runtime.class.getMethod("exec", new Class[] {String[].class, String[].class, File.class}); + } catch (NoSuchMethodException nsme) { + // OK. + } + } + /** * Creates a new execute object using PumpStreamHandler for * stream handling. *************** *** 124,156 **** * @return the commandline used to create a subprocess */ public String[] getCommandline() { ! String[] commandLine = cmdl; ! ! if (workingDirectory != null && ! !antWorkingDirectory.equals(workingDirectory.getAbsolutePath()) && ! !myos.equals("Mac OS")) { ! ! if (myos.toLowerCase().indexOf("windows") >= 0 && ! (myos.toLowerCase().indexOf("nt") >= 0 || ! myos.indexOf("2000") >= 0)) { ! ! commandLine = new String[cmdl.length+5]; ! commandLine[0] = "cmd"; ! commandLine[1] = "/c"; ! commandLine[2] = "cd"; ! commandLine[3] = workingDirectory.getAbsolutePath(); ! commandLine[4] = "&&"; ! System.arraycopy(cmdl, 0, commandLine, 5, cmdl.length); ! ! } else { ! commandLine = new String[cmdl.length+2]; ! commandLine[0] = antRun; ! commandLine[1] = workingDirectory.getAbsolutePath(); ! System.arraycopy(cmdl, 0, commandLine, 2, cmdl.length); ! } ! } ! ! return commandLine; } --- 136,142 ---- * @return the commandline used to create a subprocess */ public String[] getCommandline() { ! return cmdl; } *************** *** 187,198 **** * Sets the working directory of the process to execute. * *

This is emulated using the antRun scripts unless the OS is ! * Windows NT in which case a cmd.exe is spawned. * * @param wd the working directory of the process. */ public void setWorkingDirectory(File wd) { ! workingDirectory = wd; } /** --- 173,189 ---- * Sets the working directory of the process to execute. * *

This is emulated using the antRun scripts unless the OS is ! * Windows NT in which case a cmd.exe is spawned, ! * or MRJ and setting user.dir works, or JDK 1.3 and there is ! * official support in java.lang.Runtime. * * @param wd the working directory of the process. */ public void setWorkingDirectory(File wd) { ! if (wd == null || wd.getAbsolutePath().equals(antWorkingDirectory)) ! workingDirectory = null; ! else ! workingDirectory = wd; } /** *************** *** 201,207 **** * @param project the current project. */ public void setAntRun(Project project) throws BuildException { ! if (myos.equals("Mac OS")) return; String ant = project.getProperty("ant.home"); --- 192,198 ---- * @param project the current project. */ public void setAntRun(Project project) throws BuildException { ! if (myos.equals("Mac OS") || execWithCWD != null) return; String ant = project.getProperty("ant.home"); *************** *** 244,262 **** protected Process exec() throws IOException { ! String userDir = System.getProperty("user.dir"); ! try { ! if (myos.equals("Mac OS") && workingDirectory != null) { ! System.getProperties().put("user.dir", ! workingDirectory.getAbsolutePath()); ! } ! ! return Runtime.getRuntime().exec(getCommandline(), getEnvironment()); ! } finally { ! if (myos.equals("Mac OS") && workingDirectory != null) { ! System.getProperties().put("user.dir", userDir); ! } ! } } protected void waitFor(Process process) { --- 235,290 ---- protected Process exec() throws IOException { ! if (workingDirectory == null) { ! // Easy. ! return Runtime.getRuntime().exec(cmdl, getEnvironment()); ! } else if (execWithCWD != null) { ! // The best way to set cwd, if you have JDK 1.3. ! try { ! Object[] arguments = new Object[] {getCommandline(), getEnvironment(), workingDirectory}; ! return (Process)execWithCWD.invoke(Runtime.getRuntime(), arguments); ! } catch (InvocationTargetException ite) { ! Throwable t = ite.getTargetException(); ! if (t instanceof ThreadDeath) { ! throw (ThreadDeath)t; ! } else if (t instanceof IOException) { ! throw (IOException)t; ! } else { ! throw new IOException(t.toString()); ! } ! } catch (Exception e) { ! // IllegalAccess, IllegalArgument, ClassCast ! throw new IOException(e.toString()); ! } ! } else if (myos.equals("Mac OS")) { ! // Dubious Mac hack. ! System.getProperties().put("user.dir", ! workingDirectory.getAbsolutePath()); ! try { ! return Runtime.getRuntime().exec(cmdl, getEnvironment()); ! } finally { ! System.getProperties().put("user.dir", antWorkingDirectory); ! } ! } else if (myos.toLowerCase().indexOf("windows") >= 0 && ! (myos.toLowerCase().indexOf("nt") >= 0 || ! myos.indexOf("2000") >= 0)) { ! // cmd /c cd works OK on Windows NT & friends. ! String[] commandLine = new String[cmdl.length+5]; ! commandLine[0] = "cmd"; ! commandLine[1] = "/c"; ! commandLine[2] = "cd"; ! commandLine[3] = workingDirectory.getAbsolutePath(); ! commandLine[4] = "&&"; ! System.arraycopy(cmdl, 0, commandLine, 5, cmdl.length); ! return Runtime.getRuntime().exec(commandLine, getEnvironment()); ! } else { ! // Fallback to the antRun wrapper script (POSIX, Win95/98, etc.): ! String[] commandLine = new String[cmdl.length+2]; ! commandLine[0] = antRun; ! commandLine[1] = workingDirectory.getAbsolutePath(); ! System.arraycopy(cmdl, 0, commandLine, 2, cmdl.length); ! return Runtime.getRuntime().exec(commandLine, getEnvironment()); ! } } protected void waitFor(Process process) { --------------AA35EAD7C6617A8534E42DA8--