src/hotspot/os/windows/os_windows.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File open Cdiff src/hotspot/os/windows/os_windows.cpp

src/hotspot/os/windows/os_windows.cpp

Print this page

        

*** 4058,4076 **** PAGE_READONLY, &old_status)) { fatal("Could not enable polling page"); } } int os::stat(const char *path, struct stat *sbuf) { ! char pathbuf[MAX_PATH]; ! if (strlen(path) > MAX_PATH - 1) { ! errno = ENAMETOOLONG; return -1; } ! os::native_path(strcpy(pathbuf, path)); ! int ret = ::stat(pathbuf, sbuf); if (sbuf != NULL && UseUTCFileTimestamp) { // Fix for 6539723. st_mtime returned from stat() is dependent on // the system timezone and so can return different values for the // same file if/when daylight savings time changes. This adjustment // makes sure the same timestamp is returned regardless of the TZ. --- 4058,4161 ---- PAGE_READONLY, &old_status)) { fatal("Could not enable polling page"); } } + // combine the high and low DWORD into a ULONGLONG + static ULONGLONG make_double_word(DWORD high_word, DWORD low_word) { + ULONGLONG value = high_word; + value <<= sizeof(high_word) * 8; + value |= low_word; + return value; + } + + // Transfers data from WIN32_FILE_ATTRIBUTE_DATA structure to struct stat + static void file_attribute_data_to_stat(struct stat* sbuf, WIN32_FILE_ATTRIBUTE_DATA file_data) { + sbuf->st_size = (_off_t)make_double_word(file_data.nFileSizeHigh, file_data.nFileSizeLow); + sbuf->st_mtime = make_double_word(file_data.ftLastWriteTime.dwHighDateTime, + file_data.ftLastWriteTime.dwLowDateTime); + sbuf->st_ctime = make_double_word(file_data.ftCreationTime.dwHighDateTime, + file_data.ftCreationTime.dwLowDateTime); + sbuf->st_atime = make_double_word(file_data.ftLastAccessTime.dwHighDateTime, + file_data.ftLastAccessTime.dwLowDateTime); + if (file_data.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) { + sbuf->st_mode |= S_IFDIR; + } + if ((file_data.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) || + (file_data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)) { + sbuf->st_mode |= S_IFREG; + } + } + + // The following function is adapted from java.base/windows/native/libjava/canonicalize_md.c + // Creates an UNC path from a single byte path. Return buffer is + // allocated in C heap and needs to be freed by the caller. + // Returns NULL on error. + static wchar_t* create_unc_path(const char* path) { + 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*)os::malloc(path_len * sizeof(wchar_t), mtInternal); + if (wpath != NULL) { + ::mbstowcs_s(&converted_chars, wpath, path_len, path, path_len); + assert(converted_chars == path_len, "sanity"); + } + } else { + /* only UNC pathname includes double slashes here */ + wpath = (wchar_t*)os::malloc((path_len + 7) * sizeof(wchar_t), mtInternal); + if (wpath != NULL) { + ::wcscpy(wpath, L"\\\\?\\UNC\0"); + ::mbstowcs_s(&converted_chars, &wpath[7], path_len + 7, path, path_len); + assert(converted_chars == path_len, "sanity"); + } + } + } else { + wpath = (wchar_t*)os::malloc((path_len + 4) * sizeof(wchar_t), mtInternal); + if (wpath != NULL) { + ::wcscpy(wpath, L"\\\\?\\\0"); + ::mbstowcs_s(&converted_chars, &wpath[4], path_len + 4, path, path_len); + assert(converted_chars == path_len, "sanity"); + } + } + return wpath; + } + + static void destroy_unc_path(wchar_t* wpath) { + os::free(wpath); + } int os::stat(const char *path, struct stat *sbuf) { ! char* pathbuf = (char*)os::strdup(path, mtInternal); ! if (pathbuf == NULL) { ! errno = ENOMEM; return -1; } ! os::native_path(pathbuf); ! int ret; ! if (strlen(path) < MAX_PATH) { ! ret = ::stat(pathbuf, sbuf); ! } else { ! wchar_t* wpath = create_unc_path(pathbuf); ! if (wpath == NULL) { ! os::free(pathbuf); ! errno = ENOMEM; ! return -1; ! } ! WIN32_FILE_ATTRIBUTE_DATA file_data; ! BOOL bret = ::GetFileAttributesExW(wpath, GetFileExInfoStandard, &file_data); ! if (!bret) { ! errno = ::GetLastError(); ! ret = -1; ! } else { ! file_attribute_data_to_stat(sbuf, file_data); ! ret = 0; ! } ! destroy_unc_path(wpath); ! } if (sbuf != NULL && UseUTCFileTimestamp) { // Fix for 6539723. st_mtime returned from stat() is dependent on // the system timezone and so can return different values for the // same file if/when daylight savings time changes. This adjustment // makes sure the same timestamp is returned regardless of the TZ.
*** 4093,4102 **** --- 4178,4188 ---- DWORD tzid = GetTimeZoneInformation(&tz); int daylightBias = (tzid == TIME_ZONE_ID_DAYLIGHT) ? tz.DaylightBias : tz.StandardBias; sbuf->st_mtime += (tz.Bias + daylightBias) * 60; } + os::free(pathbuf); return ret; } #define FT2INT64(ft) \
*** 4205,4222 **** // This method is a slightly reworked copy of JDK's sysOpen // from src/windows/hpi/src/sys_api_md.c int os::open(const char *path, int oflag, int mode) { ! char pathbuf[MAX_PATH]; ! ! if (strlen(path) > MAX_PATH - 1) { ! errno = ENAMETOOLONG; return -1; } ! os::native_path(strcpy(pathbuf, path)); ! return ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode); } FILE* os::open(int fd, const char* mode) { return ::_fdopen(fd, mode); } --- 4291,4324 ---- // This method is a slightly reworked copy of JDK's sysOpen // from src/windows/hpi/src/sys_api_md.c int os::open(const char *path, int oflag, int mode) { ! char* pathbuf = (char*)os::strdup(path, mtInternal); ! if (pathbuf == NULL) { ! errno = ENOMEM; return -1; } ! os::native_path(pathbuf); ! int ret; ! if (strlen(path) < MAX_PATH) { ! ret = ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode); ! } else { ! wchar_t* wpath = create_unc_path(pathbuf); ! if (wpath == NULL) { ! os::free(pathbuf); ! errno = ENOMEM; ! return -1; ! } ! ret = ::_wopen(wpath, oflag | O_BINARY | O_NOINHERIT, mode); ! if (ret == -1) { ! errno = ::GetLastError(); ! } ! destroy_unc_path(wpath); ! } ! os::free(pathbuf); ! return ret; } FILE* os::open(int fd, const char* mode) { return ::_fdopen(fd, mode); }
src/hotspot/os/windows/os_windows.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File