8217093: Support extended-length paths in parse_manifest.c on windows
Reviewed-by: chegar, clanger
--- a/src/java.base/share/native/libjli/jli_util.h Wed Feb 06 13:57:19 2019 +0530
+++ b/src/java.base/share/native/libjli/jli_util.h Mon Jan 28 16:42:23 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -89,7 +89,8 @@
#include <process.h>
#define JLI_StrCaseCmp(p1, p2) stricmp((p1), (p2))
#define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3))
-int JLI_Snprintf(char *buffer, size_t size, const char *format, ...);
+int JLI_Snprintf(char *buffer, size_t size, const char *format, ...);
+int JLI_Open(const char* name, int flags);
JNIEXPORT void JNICALL
JLI_CmdToArgs(char *cmdline);
#define JLI_Lseek _lseeki64
@@ -101,6 +102,7 @@
#define JLI_StrCaseCmp(p1, p2) strcasecmp((p1), (p2))
#define JLI_StrNCaseCmp(p1, p2, p3) strncasecmp((p1), (p2), (p3))
#define JLI_Snprintf snprintf
+#define JLI_Open open
#define JLI_PutEnv putenv
#define JLI_GetPid getpid
#ifdef __solaris__
--- a/src/java.base/share/native/libjli/parse_manifest.c Wed Feb 06 13:57:19 2019 +0530
+++ b/src/java.base/share/native/libjli/parse_manifest.c Mon Jan 28 16:42:23 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -362,9 +362,11 @@
bp = buffer;
if (find_positions(fd, bp, &base_offset, &censtart) == -1) {
+ free(buffer);
return -1;
}
if (JLI_Lseek(fd, censtart, SEEK_SET) < (jlong) 0) {
+ free(buffer);
return -1;
}
@@ -583,7 +585,7 @@
int rc;
char *splashscreen_name = NULL;
- if ((fd = open(jarfile, O_RDONLY
+ if ((fd = JLI_Open(jarfile, O_RDONLY
#ifdef O_LARGEFILE
| O_LARGEFILE /* large file mode */
#endif
@@ -640,7 +642,7 @@
zentry entry;
void *data = NULL;
- if ((fd = open(jarfile, O_RDONLY
+ if ((fd = JLI_Open(jarfile, O_RDONLY
#ifdef O_LARGEFILE
| O_LARGEFILE /* large file mode */
#endif
@@ -688,7 +690,7 @@
char *value;
int rc;
- if ((fd = open(jarfile, O_RDONLY
+ if ((fd = JLI_Open(jarfile, O_RDONLY
#ifdef O_LARGEFILE
| O_LARGEFILE /* large file mode */
#endif
--- a/src/java.base/windows/native/libjli/java_md.c Wed Feb 06 13:57:19 2019 +0530
+++ b/src/java.base/windows/native/libjli/java_md.c Mon Jan 28 16:42:23 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,8 @@
#define JVM_DLL "jvm.dll"
#define JAVA_DLL "java.dll"
+#define ELP_PREFIX L"\\\\?\\"
+
/*
* Prototypes.
*/
@@ -495,6 +497,57 @@
return rc;
}
+/* On Windows, if _open fails, retry again with CreateFileW and
+ * "\\?\" prefix ( extended-length paths) - this allows to open paths with larger file names;
+ * otherwise we run into the MAX_PATH limitation */
+int JLI_Open(const char* name, int flags) {
+ int fd = _open(name, flags);
+ if (fd == -1 && errno == ENOENT) {
+ wchar_t* wname = NULL;
+ wchar_t* wfullname = NULL;
+ wchar_t* wfullname_w_prefix = NULL;
+ size_t wnamelen, wfullnamelen, elplen;
+ HANDLE h;
+
+ wnamelen = strlen(name) + 1;
+ wname = (wchar_t*) malloc(wnamelen*sizeof(wchar_t));
+ if (wname == NULL) {
+ goto end;
+ }
+ if (mbstowcs(wname, name, wnamelen - 1) == -1) {
+ goto end;
+ }
+ wname[wnamelen - 1] = L'\0';
+ 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;
+}
+
+
+
JNIEXPORT void JNICALL
JLI_ReportErrorMessage(const char* fmt, ...) {
va_list vl;