diff --git a/WHATSNEW b/WHATSNEW index 79ce9baa2..887822072 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -64,6 +64,10 @@ Fixed bugs: * reading of compiler args has become more defensive Bugzilla Report 53754 + * without force="true" would not only fail to overwrite a + read-only file as expected but also remove the existing file. + Bugzilla Report 53095 + Other changes: -------------- diff --git a/src/main/org/apache/tools/ant/taskdefs/Copy.java b/src/main/org/apache/tools/ant/taskdefs/Copy.java index 2d72ed69f..2bc99c22a 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Copy.java +++ b/src/main/org/apache/tools/ant/taskdefs/Copy.java @@ -898,7 +898,9 @@ public class Copy extends Task { String msg = "Failed to copy " + fromFile + " to " + toFile + " due to " + getDueTo(ioe); File targetFile = new File(toFile); - if (targetFile.exists() && !targetFile.delete()) { + if (!(ioe instanceof + ResourceUtils.ReadOnlyTargetFileException) + && targetFile.exists() && !targetFile.delete()) { msg += " and I couldn't delete the corrupt " + toFile; } if (failonerror) { @@ -980,7 +982,9 @@ public class Copy extends Task { + " to " + toFile + " due to " + getDueTo(ioe); File targetFile = new File(toFile); - if (targetFile.exists() && !targetFile.delete()) { + if (!(ioe instanceof + ResourceUtils.ReadOnlyTargetFileException) + && targetFile.exists() && !targetFile.delete()) { msg += " and I couldn't delete the corrupt " + toFile; } if (failonerror) { diff --git a/src/main/org/apache/tools/ant/util/ResourceUtils.java b/src/main/org/apache/tools/ant/util/ResourceUtils.java index e4562db55..a9d26d0a9 100644 --- a/src/main/org/apache/tools/ant/util/ResourceUtils.java +++ b/src/main/org/apache/tools/ant/util/ResourceUtils.java @@ -406,8 +406,7 @@ public class ResourceUtils { } if (destFile != null && destFile.isFile() && !destFile.canWrite()) { if (!force) { - throw new IOException("can't write to read-only destination " - + "file " + destFile); + throw new ReadOnlyTargetFileException(destFile); } else if (!FILE_UTILS.tryHardToDelete(destFile)) { throw new IOException("failed to delete read-only " + "destination file " + destFile); @@ -785,4 +784,13 @@ public class ResourceUtils { public static interface ResourceSelectorProvider { ResourceSelector getTargetSelectorForSource(Resource source); } + + /** + * @since Ant 1.9.4 + */ + public static class ReadOnlyTargetFileException extends IOException { + public ReadOnlyTargetFileException(File destFile) { + super("can't write to read-only destination file " + destFile); + } + } } diff --git a/src/tests/antunit/taskdefs/copy-test.xml b/src/tests/antunit/taskdefs/copy-test.xml index 6f0d5dfe1..51c6277c1 100644 --- a/src/tests/antunit/taskdefs/copy-test.xml +++ b/src/tests/antunit/taskdefs/copy-test.xml @@ -446,4 +446,26 @@ public class NullByteStreamResource extends Resource { + + + + + + + + + + + + + + + + + + + +