mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
8218547: Simplify JLI_Open on Windows in native code (libjli)
Reviewed-by: alanb, clanger
This commit is contained in:
parent
d6c2cc2413
commit
77ae10cd25
2 changed files with 81 additions and 63 deletions
|
@ -41,8 +41,6 @@
|
||||||
#define JVM_DLL "jvm.dll"
|
#define JVM_DLL "jvm.dll"
|
||||||
#define JAVA_DLL "java.dll"
|
#define JAVA_DLL "java.dll"
|
||||||
|
|
||||||
#define ELP_PREFIX L"\\\\?\\"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prototypes.
|
* Prototypes.
|
||||||
*/
|
*/
|
||||||
|
@ -497,57 +495,67 @@ JLI_Snprintf(char* buffer, size_t size, const char* format, ...) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* On Windows, if _open fails, retry again with CreateFileW and
|
/* taken from hotspot and slightly adjusted for jli lib;
|
||||||
* "\\?\" prefix ( extended-length paths) - this allows to open paths with larger file names;
|
* creates a UNC/ELP path from input 'path'
|
||||||
* otherwise we run into the MAX_PATH limitation */
|
* the return buffer is allocated in C heap and needs to be freed using
|
||||||
|
* JLI_MemFree by the caller.
|
||||||
|
*/
|
||||||
|
static wchar_t* create_unc_path(const char* path, errno_t* err) {
|
||||||
|
wchar_t* wpath = NULL;
|
||||||
|
size_t converted_chars = 0;
|
||||||
|
size_t path_len = strlen(path) + 1; /* includes the terminating NULL */
|
||||||
|
if (path[0] == '\\' && path[1] == '\\') {
|
||||||
|
if (path[2] == '?' && path[3] == '\\') {
|
||||||
|
/* if it already has a \\?\ don't do the prefix */
|
||||||
|
wpath = (wchar_t*) JLI_MemAlloc(path_len * sizeof(wchar_t));
|
||||||
|
if (wpath != NULL) {
|
||||||
|
*err = mbstowcs_s(&converted_chars, wpath, path_len, path, path_len);
|
||||||
|
} else {
|
||||||
|
*err = ENOMEM;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* only UNC pathname includes double slashes here */
|
||||||
|
wpath = (wchar_t*) JLI_MemAlloc((path_len + 7) * sizeof(wchar_t));
|
||||||
|
if (wpath != NULL) {
|
||||||
|
wcscpy(wpath, L"\\\\?\\UNC\0");
|
||||||
|
*err = mbstowcs_s(&converted_chars, &wpath[7], path_len, path, path_len);
|
||||||
|
} else {
|
||||||
|
*err = ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wpath = (wchar_t*) JLI_MemAlloc((path_len + 4) * sizeof(wchar_t));
|
||||||
|
if (wpath != NULL) {
|
||||||
|
wcscpy(wpath, L"\\\\?\\\0");
|
||||||
|
*err = mbstowcs_s(&converted_chars, &wpath[4], path_len, path, path_len);
|
||||||
|
} else {
|
||||||
|
*err = ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wpath;
|
||||||
|
}
|
||||||
|
|
||||||
int JLI_Open(const char* name, int flags) {
|
int JLI_Open(const char* name, int flags) {
|
||||||
int fd = _open(name, flags);
|
int fd;
|
||||||
if (fd == -1 && errno == ENOENT) {
|
if (strlen(name) < MAX_PATH) {
|
||||||
wchar_t* wname = NULL;
|
fd = _open(name, flags);
|
||||||
wchar_t* wfullname = NULL;
|
} else {
|
||||||
wchar_t* wfullname_w_prefix = NULL;
|
errno_t err = ERROR_SUCCESS;
|
||||||
size_t wnamelen, wfullnamelen, elplen;
|
wchar_t* wpath = create_unc_path(name, &err);
|
||||||
HANDLE h;
|
if (err != ERROR_SUCCESS) {
|
||||||
|
if (wpath != NULL) JLI_MemFree(wpath);
|
||||||
wnamelen = strlen(name) + 1;
|
errno = err;
|
||||||
wname = (wchar_t*) malloc(wnamelen*sizeof(wchar_t));
|
return -1;
|
||||||
if (wname == NULL) {
|
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
if (mbstowcs(wname, name, wnamelen - 1) == -1) {
|
fd = _wopen(wpath, flags);
|
||||||
goto end;
|
if (fd == -1) {
|
||||||
|
errno = GetLastError();
|
||||||
}
|
}
|
||||||
wname[wnamelen - 1] = L'\0';
|
JLI_MemFree(wpath);
|
||||||
wfullname = _wfullpath(wfullname, wname, 0);
|
|
||||||
if (wfullname == NULL) {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
wfullnamelen = wcslen(wfullname);
|
|
||||||
if (wfullnamelen > 247) {
|
|
||||||
elplen = wcslen(ELP_PREFIX);
|
|
||||||
wfullname_w_prefix = (wchar_t*) malloc((elplen+wfullnamelen+1)*sizeof(wchar_t));
|
|
||||||
wcscpy(wfullname_w_prefix, ELP_PREFIX);
|
|
||||||
wcscpy(wfullname_w_prefix+elplen, wfullname);
|
|
||||||
|
|
||||||
h = CreateFileW(wfullname_w_prefix, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|
||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
if (h == INVALID_HANDLE_VALUE) {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
/* associates fd with handle */
|
|
||||||
fd = _open_osfhandle((intptr_t)h, _O_RDONLY);
|
|
||||||
}
|
|
||||||
end:
|
|
||||||
free(wname);
|
|
||||||
free(wfullname);
|
|
||||||
free(wfullname_w_prefix);
|
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
JLI_ReportErrorMessage(const char* fmt, ...) {
|
JLI_ReportErrorMessage(const char* fmt, ...) {
|
||||||
va_list vl;
|
va_list vl;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938
|
* @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938
|
||||||
* 6894719 6968053 7151434 7146424 8007333 8077822 8143640 8132379
|
* 6894719 6968053 7151434 7146424 8007333 8077822 8143640 8132379 8218547
|
||||||
* @summary Argument parsing validation.
|
* @summary Argument parsing validation.
|
||||||
* @modules jdk.compiler
|
* @modules jdk.compiler
|
||||||
* jdk.zipfs
|
* jdk.zipfs
|
||||||
|
@ -36,6 +36,9 @@
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -55,20 +58,6 @@ public class Arrrghs extends TestHelper {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* SIGH, On Windows all strings are quoted, we need to unwrap it
|
|
||||||
*/
|
|
||||||
private static String removeExtraQuotes(String in) {
|
|
||||||
if (isWindows) {
|
|
||||||
// Trim the string and remove the enclosed quotes if any.
|
|
||||||
in = in.trim();
|
|
||||||
if (in.startsWith("\"") && in.endsWith("\"")) {
|
|
||||||
return in.substring(1, in.length()-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the pattern we hope to see in the output
|
// the pattern we hope to see in the output
|
||||||
static final Pattern ArgPattern = Pattern.compile("\\s*argv\\[[0-9]*\\].*=.*");
|
static final Pattern ArgPattern = Pattern.compile("\\s*argv\\[[0-9]*\\].*=.*");
|
||||||
|
|
||||||
|
@ -489,6 +478,27 @@ public class Arrrghs extends TestHelper {
|
||||||
System.out.println(tr);
|
System.out.println(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests -jar command on a jar file with "long" (> 260 chars) full path on Windows
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
void testLongPathJarFile() throws IOException {
|
||||||
|
if (!isWindows) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// put the jar file to a location with long path
|
||||||
|
String longPathPart = "longpathtest_longpathtest/";
|
||||||
|
String longPathStr = longPathPart.repeat(15);
|
||||||
|
Path longPath = Paths.get(longPathStr);
|
||||||
|
Path jarPath = Files.createDirectories(longPath).resolve("elp.jar");
|
||||||
|
File elp = jarPath.toFile();
|
||||||
|
createJar(elp, new File("Foo"), "public static void main(String[] args){ System.out.println(\"Hello from ELP\"); }");
|
||||||
|
System.out.println("execute " + elp.getAbsolutePath());
|
||||||
|
TestResult tr = doExec(javaCmd, "-jar", elp.getAbsolutePath());
|
||||||
|
tr.checkPositive();
|
||||||
|
tr.contains("Hello from ELP");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tests various dispositions of the main method, these tests are limited
|
* Tests various dispositions of the main method, these tests are limited
|
||||||
* to English locales as they check for error messages that are localized.
|
* to English locales as they check for error messages that are localized.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue