Return-Path: Delivered-To: apmail-ant-notifications-archive@locus.apache.org Received: (qmail 76573 invoked from network); 10 Oct 2008 04:50:06 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 10 Oct 2008 04:50:06 -0000 Received: (qmail 72339 invoked by uid 500); 10 Oct 2008 04:50:00 -0000 Delivered-To: apmail-ant-notifications-archive@ant.apache.org Received: (qmail 72320 invoked by uid 500); 10 Oct 2008 04:50:00 -0000 Mailing-List: contact notifications-help@ant.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ant.apache.org Delivered-To: mailing list notifications@ant.apache.org Received: (qmail 72310 invoked by uid 99); 10 Oct 2008 04:50:00 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 09 Oct 2008 21:50:00 -0700 X-ASF-Spam-Status: No, hits=-1998.4 required=10.0 tests=ALL_TRUSTED,DNS_FROM_SECURITYSAGE,TVD_FUZZY_SYMBOL X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 10 Oct 2008 04:49:03 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 543C523889B7; Thu, 9 Oct 2008 21:49:09 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r703318 - in /ant/core/trunk/src/main/org/apache/tools/ant: taskdefs/optional/unix/Symlink.java util/SymbolicLinkUtils.java Date: Fri, 10 Oct 2008 04:49:09 -0000 To: notifications@ant.apache.org From: bodewig@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20081010044909.543C523889B7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: bodewig Date: Thu Oct 9 21:49:08 2008 New Revision: 703318 URL: http://svn.apache.org/viewvc?rev=703318&view=rev Log: Move delete method to SymbolicLinkUtils Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java ant/core/trunk/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java?rev=703318&r1=703317&r2=703318&view=diff ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java Thu Oct 9 21:49:08 2008 @@ -185,7 +185,7 @@ return; } log("Removing symlink: " + link); - deleteSymlink(link, this); + SYMLINK_UTILS.deleteSymbolicLink(new File(link), this); } catch (FileNotFoundException fnfe) { handleError(fnfe.toString()); } catch (IOException ioe) { @@ -219,7 +219,7 @@ doLink(res, lnk); } else if (!test.getCanonicalPath().equals( new File(res).getCanonicalPath())) { - deleteSymlink(lnk, this); + SYMLINK_UTILS.deleteSymbolicLink(test, this); doLink(res, lnk); } // else lnk exists, do nothing } catch (IOException ioe) { @@ -378,32 +378,13 @@ * File that doesn't exist. * @throws IOException If calls to File.rename * or File.delete fail. - * @deprecated use the two-arg version which also works if the link's - * target can not be renamed. + * @deprecated use + * org.apache.tools.ant.util.SymbolicLinkUtils#deleteSymbolicLink + * instead */ public static void deleteSymlink(String path) throws IOException, FileNotFoundException { - deleteSymlink(new File(path)); - } - - /** - * Delete a symlink (without deleting the associated resource). - * - *

This is a convenience method that simply invokes - * deleteSymlink(java.io.File). - * - * @param path A string containing the path of the symlink to delete. - * @param task An Ant Task required if "rm" needs to be invoked. - * - * @throws FileNotFoundException When the path results in a - * File that doesn't exist. - * @throws IOException If calls to File.rename - * or File.delete fail. - * @since Ant 1.8.0 - */ - public static void deleteSymlink(String path, Task t) - throws IOException, FileNotFoundException { - deleteSymlink(new File(path), t); + SYMLINK_UTILS.deleteSymbolicLink(new File(path), null); } /** @@ -411,8 +392,7 @@ * *

This is a utility method that removes a unix symlink without removing * the resource that the symlink points to. If it is accidentally invoked - * on a real file, the real file will not be harmed, but an exception - * will be thrown when the deletion is attempted.

+ * on a real file, the real file will not be harmed.

* *

This method works by * getting the canonical path of the link, using the canonical path to @@ -431,118 +411,13 @@ * File.delete or * File.getCanonicalPath * fail. - * @deprecated use the two-arg version which also works if the link's - * target can not be renamed. + * @deprecated use + * org.apache.tools.ant.util.SymbolicLinkUtils#deleteSymbolicLink + * instead */ public static void deleteSymlink(File linkfil) throws IOException { - deleteSymlink(linkfil, null); - } - - /** - * Delete a symlink (without deleting the associated resource). - * - *

This is a utility method that removes a unix symlink without removing - * the resource that the symlink points to. If it is accidentally invoked - * on a real file, the real file will not be harmed, but an exception - * will be thrown when the deletion is attempted.

- * - *

Normaly this method works by - * getting the canonical path of the link, using the canonical path to - * rename the resource (breaking the link) and then deleting the link. - * The resource is then returned to its original name inside a finally - * block to ensure that the resource is unharmed even in the event of - * an exception.

- * - *

There may be cases where the algorithm described above doesn't work, - * in that case the method tries to use the native "rm" command on - * the symlink instead.

- * - * @param linkfil A File object of the symlink to delete. - * @param task An Ant Task required if "rm" needs to be invoked. - * - * @throws IOException If calls to File.rename, - * File.delete or - * File.getCanonicalPath - * fail. - * @since Ant 1.8.0 - */ - public static void deleteSymlink(File linkfil, Task task) - throws IOException { - if (SYMLINK_UTILS.isDanglingSymbolicLink(linkfil.getParentFile(), - linkfil.getName())) { - linkfil.delete(); - return; - } - - if (!SYMLINK_UTILS.isSymbolicLink(linkfil.getParentFile(), - linkfil.getName())) { - // plain file, not a link - return; - } - - if (!linkfil.exists()) { - throw new FileNotFoundException("No such symlink: " + linkfil); - } - - // find the resource of the existing link: - File canfil = linkfil.getCanonicalFile(); - - // no reason to try the renaming algorithm if we aren't allowed to - // write to the target's parent directory. Let's hope that - // File.canWrite works on all platforms. - - if (task == null || canfil.getParentFile().canWrite()) { - - // rename the resource, thus breaking the link: - File temp = FILE_UTILS.createTempFile("symlink", ".tmp", - canfil.getParentFile(), false, - false); - - if (FILE_UTILS.isLeadingPath(canfil, linkfil)) { - // link points to a parent directory, renaming the parent - // will rename the file - linkfil = new File(temp, - FILE_UTILS.removeLeadingPath(canfil, - linkfil)); - } - - boolean renamedTarget = false; - try { - try { - FILE_UTILS.rename(canfil, temp); - renamedTarget = true; - } catch (IOException e) { - throw new IOException("Couldn't rename resource when " - + "attempting to delete " + linkfil); - } - // delete the (now) broken link: - if (!linkfil.delete()) { - throw new IOException("Couldn't delete symlink: " - + linkfil - + " (was it a real file? is this " - + "not a UNIX system?)"); - } - } finally { - if (renamedTarget) { - // return the resource to its original name: - try { - FILE_UTILS.rename(temp, canfil); - } catch (IOException e) { - throw new IOException("Couldn't return resource " - + temp - + " to its original name: " - + canfil.getAbsolutePath() - + "\n THE RESOURCE'S NAME ON DISK" - + " HAS BEEN CHANGED BY THIS" - + " ERROR!\n"); - } - } - } - } else { - Execute.runCommand(task, - new String[] {"rm", linkfil.getAbsolutePath()}); - } + SYMLINK_UTILS.deleteSymbolicLink(linkfil, null); } /** @@ -597,7 +472,7 @@ options += "f"; if (linkfil.exists()) { try { - deleteSymlink(linkfil); + SYMLINK_UTILS.deleteSymbolicLink(linkfil, this); } catch (FileNotFoundException fnfe) { log("Symlink disappeared before it was deleted: " + lnk); } catch (IOException ioe) { Modified: ant/core/trunk/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java?rev=703318&r1=703317&r2=703318&view=diff ============================================================================== --- ant/core/trunk/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java (original) +++ ant/core/trunk/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java Thu Oct 9 21:49:08 2008 @@ -18,8 +18,12 @@ package org.apache.tools.ant.util; import java.io.File; +import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.taskdefs.Execute; /** * Contains methods related to symbolic links - or what Ant thinks is @@ -179,4 +183,111 @@ return false; } + /** + * Delete a symlink (without deleting the associated resource). + * + *

This is a utility method that removes a unix symlink without + * removing the resource that the symlink points to. If it is + * accidentally invoked on a real file, the real file will not be + * harmed, but silently ignored.

+ * + *

Normaly this method works by + * getting the canonical path of the link, using the canonical path to + * rename the resource (breaking the link) and then deleting the link. + * The resource is then returned to its original name inside a finally + * block to ensure that the resource is unharmed even in the event of + * an exception.

+ * + *

There may be cases where the algorithm described above doesn't work, + * in that case the method tries to use the native "rm" command on + * the symlink instead.

+ * + * @param link A File object of the symlink to delete. + * @param task An Ant Task required if "rm" needs to be invoked. + * + * @throws IOException If calls to File.rename, + * File.delete or File.getCanonicalPath + * fail. + * @throws BuildException if the execution of "rm" failed. + */ + public void deleteSymbolicLink(File link, Task task) + throws IOException { + if (isDanglingSymbolicLink(link)) { + if (!link.delete()) { + throw new IOException("failed to remove dangling symbolic link " + + link); + } + return; + } + + if (!isSymbolicLink(link)) { + // plain file, not a link + return; + } + + if (!link.exists()) { + throw new FileNotFoundException("No such symbolic link: " + link); + } + + // find the resource of the existing link: + File target = link.getCanonicalFile(); + + // no reason to try the renaming algorithm if we aren't allowed to + // write to the target's parent directory. Let's hope that + // File.canWrite works on all platforms. + + if (task == null || target.getParentFile().canWrite()) { + + // rename the resource, thus breaking the link: + File temp = FILE_UTILS.createTempFile("symlink", ".tmp", + target.getParentFile(), false, + false); + + if (FILE_UTILS.isLeadingPath(target, link)) { + // link points to a parent directory, renaming the parent + // will rename the file + link = new File(temp, + FILE_UTILS.removeLeadingPath(target, link)); + } + + boolean renamedTarget = false; + try { + try { + FILE_UTILS.rename(target, temp); + renamedTarget = true; + } catch (IOException e) { + throw new IOException("Couldn't rename resource when " + + "attempting to delete '" + link + + "'. Reason: " + e.getMessage()); + } + // delete the (now) broken link: + if (!link.delete()) { + throw new IOException("Couldn't delete symlink: " + + link + + " (was it a real file? is this " + + "not a UNIX system?)"); + } + } finally { + if (renamedTarget) { + // return the resource to its original name: + try { + FILE_UTILS.rename(temp, target); + } catch (IOException e) { + throw new IOException("Couldn't return resource " + + temp + + " to its original name: " + + target.getAbsolutePath() + + ". Reason: " + e.getMessage() + + "\n THE RESOURCE'S NAME ON DISK" + + " HAS BEEN CHANGED BY THIS" + + " ERROR!\n"); + } + } + } + } else { + Execute.runCommand(task, + new String[] {"rm", link.getAbsolutePath()}); + } + } + } \ No newline at end of file