aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/windows
diff options
context:
space:
mode:
authorGravatar Laszlo Csomor <laszlocsomor@google.com>2016-12-15 11:16:44 +0000
committerGravatar John Cater <jcater@google.com>2016-12-15 20:37:48 +0000
commitaa1614b6a081ea435c536ef2b93c270dd5b071b8 (patch)
tree64e250114685ca07827c04317e17afb8bc1ea074 /src/main/java/com/google/devtools/build/lib/windows
parentf00cee8a049ee0456f3aab7128ba06d33b7583b3 (diff)
Windows, JNI: implement nativeGetLongPath
Implement a JNI method that can resolve 8dot3 style paths. This is necessary because we need to be able to compare 8dot3 style paths and long paths [1], and because implementing this correctly in Java seems to be impossible [2]. This change also adds tests for the JNI isJunction implementation. See https://github.com/bazelbuild/bazel/issues/2101 [1] https://github.com/bazelbuild/bazel/issues/2145 [2] https://github.com/bazelbuild/bazel/issues/2145#issuecomment-266766716 -- PiperOrigin-RevId: 142123750 MOS_MIGRATED_REVID=142123750
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/windows')
-rw-r--r--src/main/java/com/google/devtools/build/lib/windows/WindowsFileOperations.java34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/windows/WindowsFileOperations.java b/src/main/java/com/google/devtools/build/lib/windows/WindowsFileOperations.java
index 0eb287e372..d95f9025b0 100644
--- a/src/main/java/com/google/devtools/build/lib/windows/WindowsFileOperations.java
+++ b/src/main/java/com/google/devtools/build/lib/windows/WindowsFileOperations.java
@@ -30,6 +30,8 @@ public class WindowsFileOperations {
static native int nativeIsJunction(String path, String[] error);
+ static native boolean nativeGetLongPath(String path, String[] result, String[] error);
+
/** Determines whether `path` is a junction point or directory symlink. */
public static boolean isJunction(String path) throws IOException {
WindowsJniLoader.loadJni();
@@ -44,7 +46,37 @@ public class WindowsFileOperations {
}
}
+ /**
+ * Returns the long path associated with the input `path`.
+ *
+ * <p>This method resolves all 8dot3 style components of the path and returns the long format. For
+ * example, if the input is "C:/progra~1/micros~1" the result may be "C:\Program Files\Microsoft
+ * Visual Studio 14.0". The returned path is Windows-style in that it uses backslashes, even if
+ * the input uses forward slashes.
+ *
+ * <p>May return an UNC path if `path` or its resolution is sufficiently long.
+ *
+ * @throws IOException if the `path` is not found or some other I/O error occurs
+ */
+ public static String getLongPath(String path) throws IOException {
+ String[] result = new String[] {null};
+ String[] error = new String[] {null};
+ if (nativeGetLongPath(asLongPath(path), result, error)) {
+ return result[0];
+ } else {
+ throw new IOException(error[0]);
+ }
+ }
+
+ /**
+ * Returns a Windows-style path suitable to pass to Widechar Win32 API functions.
+ *
+ * <p>Returns an UNC path if `path` is longer than `MAX_PATH` (in <windows.h>). If it's shorter or
+ * is already an UNC path, then this method returns `path` itself.
+ */
static String asLongPath(String path) {
- return "\\\\?\\" + path.replace('/', '\\');
+ return path.length() > 260 && !path.startsWith("\\\\?\\")
+ ? ("\\\\?\\" + path.replace('/', '\\'))
+ : path;
}
}