From 5348fe6bcba126301a3f97e3919f7eeca1b940ea Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Thu, 4 Sep 2008 14:57:04 +0000 Subject: [PATCH] symlink delete now works if the link points to a parent directory as well. PR 45743. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@692081 13f79535-47bb-0310-9956-ffa450edef68 --- WHATSNEW | 4 ++++ .../ant/taskdefs/optional/unix/Symlink.java | 20 ++++++++++++++-- .../antunit/core/dirscanner-symlinks-test.xml | 24 +++++-------------- .../taskdefs/optional/unix/symlink-test.xml | 6 +++++ 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/WHATSNEW b/WHATSNEW index 1f25ac778..5f3e810c9 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -196,6 +196,10 @@ Fixed bugs: contained line feeds some excess output ended up in Ant's log. Bugzilla Report 45411. + * failed to delete a link that pointed to + a parent directory. + Bugzilla Report 45743. + Other changes: -------------- diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java b/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java index 0d2d2b2e5..c64b8225d 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java @@ -386,13 +386,19 @@ public class Symlink extends DispatchTask { *

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. This method works by + * 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.

+ * *

Since Ant 1.8.0 this method will try to delete the File object if * it reports it wouldn't exist (as symlinks pointing nowhere usually do). * Prior version would throw a FileNotFoundException in that case.

@@ -410,12 +416,22 @@ public class Symlink extends DispatchTask { linkfil.delete(); return; } + // find the resource of the existing link: File canfil = linkfil.getCanonicalFile(); // rename the resource, thus breaking the link: File temp = FILE_UTILS.createTempFile("symlink", ".tmp", - canfil.getParentFile(), false, false); + 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)); + } + try { try { FILE_UTILS.rename(canfil, temp); diff --git a/src/tests/antunit/core/dirscanner-symlinks-test.xml b/src/tests/antunit/core/dirscanner-symlinks-test.xml index 17c6e2705..3e1251207 100644 --- a/src/tests/antunit/core/dirscanner-symlinks-test.xml +++ b/src/tests/antunit/core/dirscanner-symlinks-test.xml @@ -81,9 +81,7 @@ - - - + @@ -95,9 +93,7 @@ - - - + @@ -110,9 +106,7 @@ - - - + @@ -122,9 +116,7 @@ - - - + @@ -134,9 +126,7 @@ - - - + @@ -146,9 +136,7 @@ - - - + diff --git a/src/tests/antunit/taskdefs/optional/unix/symlink-test.xml b/src/tests/antunit/taskdefs/optional/unix/symlink-test.xml index 2a1cdfa02..91bd1651b 100644 --- a/src/tests/antunit/taskdefs/optional/unix/symlink-test.xml +++ b/src/tests/antunit/taskdefs/optional/unix/symlink-test.xml @@ -69,4 +69,10 @@ + + + + + +