diff options
author | Alexander Nittka <alex@nittka.de> | 2020-03-13 14:16:50 +0100 |
---|---|---|
committer | Thomas Wolf <thomas.wolf@paranor.ch> | 2020-04-03 19:30:31 +0200 |
commit | bc4ed530a5f19b5dae77f3aa76369003bd6c3599 (patch) | |
tree | 26f0092c372d7307589a071d83e550ed4365353a | |
parent | 9aaa58052b4f810da7a1b3cd67dadbd50e956934 (diff) | |
download | jgit-bc4ed530a5f19b5dae77f3aa76369003bd6c3599.tar.gz jgit-bc4ed530a5f19b5dae77f3aa76369003bd6c3599.zip |
FileUtils: improve delete (Windows)
Ensure files are writable before trying to delete them.
Bug: 408846
Change-Id: I930a547594bba853c33634ae54bd64d236afade3
Signed-off-by: Alexander Nittka <alex@nittka.de>
-rw-r--r-- | org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java | 37 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java | 51 |
2 files changed, 70 insertions, 18 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java index f9ec5d8d6f..2b1fb2ef04 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java @@ -79,6 +79,15 @@ public class FileUtilsTest { } @Test + public void testDeleteReadOnlyFile() throws IOException { + File f = new File(trash, "f"); + FileUtils.createNewFile(f); + assertTrue(f.setReadOnly()); + FileUtils.delete(f); + assertFalse(f.exists()); + } + + @Test public void testDeleteRecursive() throws IOException { File f1 = new File(trash, "test/test/a"); FileUtils.mkdirs(f1.getParentFile()); @@ -339,6 +348,34 @@ public class FileUtilsTest { } @Test + public void testDeleteNonRecursiveTreeNotOk() throws IOException { + File t = new File(trash, "t"); + FileUtils.mkdir(t); + File f = new File(t, "f"); + FileUtils.createNewFile(f); + try { + FileUtils.delete(t, FileUtils.EMPTY_DIRECTORIES_ONLY); + fail("expected failure to delete f"); + } catch (IOException e) { + assertTrue(e.getMessage().endsWith(t.getAbsolutePath())); + } + assertTrue(f.exists()); + assertTrue(t.exists()); + } + + @Test + public void testDeleteNonRecursiveTreeIgnoreError() throws IOException { + File t = new File(trash, "t"); + FileUtils.mkdir(t); + File f = new File(t, "f"); + FileUtils.createNewFile(f); + FileUtils.delete(t, + FileUtils.EMPTY_DIRECTORIES_ONLY | FileUtils.IGNORE_ERRORS); + assertTrue(f.exists()); + assertTrue(t.exists()); + } + + @Test public void testRenameOverNonExistingFile() throws IOException { File d = new File(trash, "d"); FileUtils.mkdirs(d); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java index 4831fbb64e..c43956e53d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.nio.channels.FileChannel; import java.nio.file.AtomicMoveNotSupportedException; import java.nio.file.CopyOption; +import java.nio.file.DirectoryNotEmptyException; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.LinkOption; @@ -180,21 +181,31 @@ public class FileUtils { } if (delete) { - Throwable t = null; + IOException t = null; Path p = f.toPath(); - try { - Files.delete(p); - return; - } catch (FileNotFoundException e) { - if ((options & (SKIP_MISSING | IGNORE_ERRORS)) == 0) { - throw new IOException(MessageFormat.format( - JGitText.get().deleteFileFailed, - f.getAbsolutePath()), e); + boolean tryAgain; + do { + tryAgain = false; + try { + Files.delete(p); + return; + } catch (NoSuchFileException | FileNotFoundException e) { + handleDeleteException(f, e, options, + SKIP_MISSING | IGNORE_ERRORS); + return; + } catch (DirectoryNotEmptyException e) { + handleDeleteException(f, e, options, IGNORE_ERRORS); + return; + } catch (IOException e) { + if (!f.canWrite()) { + tryAgain = f.setWritable(true); + } + if (!tryAgain) { + t = e; + } } - return; - } catch (IOException e) { - t = e; - } + } while (tryAgain); + if ((options & RETRY) != 0) { for (int i = 1; i < 10; i++) { try { @@ -210,11 +221,15 @@ public class FileUtils { } } } - if ((options & IGNORE_ERRORS) == 0) { - throw new IOException(MessageFormat.format( - JGitText.get().deleteFileFailed, f.getAbsolutePath()), - t); - } + handleDeleteException(f, t, options, IGNORE_ERRORS); + } + } + + private static void handleDeleteException(File f, IOException e, + int allOptions, int checkOptions) throws IOException { + if (e != null && (allOptions & checkOptions) == 0) { + throw new IOException(MessageFormat.format( + JGitText.get().deleteFileFailed, f.getAbsolutePath()), e); } } |