diff options
author | 2018-07-09 04:32:32 -0700 | |
---|---|---|
committer | 2018-07-09 04:33:56 -0700 | |
commit | c2b70f1e28b8fbc002efbac16d555f941c7d59a3 (patch) | |
tree | 79b2ab5eb0e1a7e4d971b94ba01e6415f7e6b5cd /src/main/java/com/google/devtools/build/lib/windows | |
parent | 4304542a7438acaeb09559e71a971e56fbecc4e5 (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.java | 37 |
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])); } |