aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/windows
diff options
context:
space:
mode:
authorGravatar Laszlo Csomor <laszlocsomor@google.com>2018-07-09 04:32:32 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-07-09 04:33:56 -0700
commitc2b70f1e28b8fbc002efbac16d555f941c7d59a3 (patch)
tree79b2ab5eb0e1a7e4d971b94ba01e6415f7e6b5cd /src/main/java/com/google/devtools/build/lib/windows
parent4304542a7438acaeb09559e71a971e56fbecc4e5 (diff)
Windows,JNI: more robust nativeCreateJunction
Rewrite the CreateJunction function in the Windows JNI library. The new implementation's improvements: - succeeds if the junction already exists with the desired target; hopefully this will fix issue https://github.com/bazelbuild/bazel/issues/5433 - tolerant to concurrent filesystem modifications, e.g. if the junction's path suddenly disappears, the function reports the error correctly Fixes https://github.com/bazelbuild/bazel/issues/5433 Change-Id: I58a2314a00f6edaa7c36c35ba54616168b44eb7d Closes #5528. Change-Id: I9f5dc9237b70a433d0d8c2578a826de3d462d110 PiperOrigin-RevId: 203744515
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/windows')
-rw-r--r--src/main/java/com/google/devtools/build/lib/windows/jni/WindowsFileOperations.java37
1 files changed, 35 insertions, 2 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/windows/jni/WindowsFileOperations.java b/src/main/java/com/google/devtools/build/lib/windows/jni/WindowsFileOperations.java
index 6a16ab8aab..229c207e91 100644
--- a/src/main/java/com/google/devtools/build/lib/windows/jni/WindowsFileOperations.java
+++ b/src/main/java/com/google/devtools/build/lib/windows/jni/WindowsFileOperations.java
@@ -49,6 +49,16 @@ public class WindowsFileOperations {
private static final int IS_JUNCTION_NO = 1;
private static final int IS_JUNCTION_ERROR = 2;
+ // Keep CREATE_JUNCTION_* values in sync with src/main/native/windows/file.cc.
+ private static final int CREATE_JUNCTION_SUCCESS = 0;
+ private static final int CREATE_JUNCTION_ERROR = 1;
+ private static final int CREATE_JUNCTION_TARGET_NAME_TOO_LONG = 2;
+ private static final int CREATE_JUNCTION_PARENT_MISSING = 3;
+ private static final int CREATE_JUNCTION_ALREADY_EXISTS_WITH_DIFFERENT_TARGET = 4;
+ private static final int CREATE_JUNCTION_ALREADY_EXISTS_BUT_NOT_A_JUNCTION = 5;
+ private static final int CREATE_JUNCTION_ACCESS_DENIED = 6;
+ private static final int CREATE_JUNCTION_DISAPPEARED = 7;
+
// Keep DELETE_PATH_* values in sync with src/main/native/windows/file.cc.
private static final int DELETE_PATH_SUCCESS = 0;
private static final int DELETE_PATH_DOES_NOT_EXIST = 1;
@@ -60,7 +70,7 @@ public class WindowsFileOperations {
private static native boolean nativeGetLongPath(String path, String[] result, String[] error);
- private static native boolean nativeCreateJunction(String name, String target, String[] error);
+ private static native int nativeCreateJunction(String name, String target, String[] error);
private static native int nativeDeletePath(String path, String[] error);
@@ -125,7 +135,30 @@ public class WindowsFileOperations {
public static void createJunction(String name, String target) throws IOException {
WindowsJniLoader.loadJni();
String[] error = new String[] {null};
- if (!nativeCreateJunction(name.replace('/', '\\'), target.replace('/', '\\'), error)) {
+ int result = nativeCreateJunction(name.replace('/', '\\'), target.replace('/', '\\'), error);
+ if (result != CREATE_JUNCTION_SUCCESS) {
+ switch (result) {
+ case CREATE_JUNCTION_TARGET_NAME_TOO_LONG:
+ error[0] = "target name is too long";
+ break;
+ case CREATE_JUNCTION_PARENT_MISSING:
+ error[0] = "a parent directory is missing";
+ break;
+ case CREATE_JUNCTION_ALREADY_EXISTS_WITH_DIFFERENT_TARGET:
+ error[0] = "junction already exists with different target";
+ break;
+ case CREATE_JUNCTION_ALREADY_EXISTS_BUT_NOT_A_JUNCTION:
+ error[0] = "a file or directory already exists at the junction's path";
+ break;
+ case CREATE_JUNCTION_ACCESS_DENIED:
+ error[0] = "access is denied";
+ break;
+ case CREATE_JUNCTION_DISAPPEARED:
+ error[0] = "the junction's path got modified unexpectedly";
+ break;
+ default:
+ break;
+ }
throw new IOException(
String.format("Cannot create junction (name=%s, target=%s): %s", name, target, error[0]));
}