Skip to content

Commit

Permalink
[FIXED JENKINS-17681] Do not try to call resolveSymlink on a nonexist…
Browse files Browse the repository at this point in the history
…ent link as you will just get an IOException, breaking peephole permalinks in some Windows environments.
  • Loading branch information
jglick committed May 2, 2013
1 parent 00d5e38 commit 3c2b50e
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 1 deletion.
3 changes: 3 additions & 0 deletions changelog.html
Expand Up @@ -58,6 +58,9 @@
<li class=bug>
Display Name is not shown.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-17715">issue 17715</a>)
<li class='major bug'>
Symlink handling problem with build permalinks on Windows.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-17681">issue 17681</a>)
<li class=bug>
List views missing a required field were unloadable.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-15309">issue 15309</a>)
Expand Down
4 changes: 4 additions & 0 deletions core/src/main/java/hudson/Util.java
Expand Up @@ -1200,6 +1200,10 @@ public static String resolveSymlink(File link) throws InterruptedException, IOEx
} catch (ClassNotFoundException x3) {
assert false : x3; // should be Java 7+ here
}
if (x2.getClass().getName().equals("java.nio.file.FileSystemException")) {
// Thrown ("Incorrect function.") on JDK 7u21 in Windows 2012 when called on a non-symlink, rather than NotLinkException, contrary to documentation. Maybe only when not on NTFS?
return null;
}
if (x2 instanceof IOException) {
throw (IOException) x2;
}
Expand Down
10 changes: 9 additions & 1 deletion core/src/main/java/jenkins/model/PeepholePermalink.java
Expand Up @@ -17,6 +17,7 @@
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -143,6 +144,12 @@ protected void updateCache(@Nonnull Job<?,?> job, @Nullable Run<?,?> b) {
}
}

// File.exists returns false for a link with a missing target, so for Java 6 compatibility we have to use this circuitous method to see if it was created.
private static boolean exists(File link) {
File[] kids = link.getParentFile().listFiles();
return kids != null && Arrays.asList(kids).contains(link);
}

static String readSymlink(File cache) throws IOException, InterruptedException {
String target = Util.resolveSymlink(cache);
if (target==null && cache.exists()) {
Expand All @@ -158,7 +165,8 @@ static void writeSymlink(File cache, String target) throws IOException, Interrup
File tmp = new File(cache.getPath()+".tmp");
try {
Util.createSymlink(tmp.getParentFile(),target,tmp.getName(),listener);
if (Util.resolveSymlink(tmp)==null) {
// Avoid calling resolveSymlink on a nonexistent file as it will probably throw an IOException:
if (!exists(tmp) || Util.resolveSymlink(tmp)==null) {
// symlink not supported. use a regular file
AtomicFileWriter cw = new AtomicFileWriter(cache);
try {
Expand Down

0 comments on commit 3c2b50e

Please sign in to comment.