intptr_t omrfile_open(struct OMRPortLibrary *portLibrary, const char *path, int32_t flags, int32_t mode) { DWORD accessMode, shareMode, createMode, flagsAndAttributes; HANDLE aHandle; int32_t error = 0; wchar_t unicodeBuffer[UNICODE_BUFFER_SIZE], *unicodePath; SECURITY_ATTRIBUTES sAttrib; Trc_PRT_file_open_Entry(path, flags, mode); /* Convert the filename from UTF8 to Unicode */ unicodePath = file_get_unicode_path(portLibrary, path, unicodeBuffer, UNICODE_BUFFER_SIZE); if (NULL == unicodePath) { return -1; } accessMode = 0; if (flags & EsOpenRead) { accessMode |= GENERIC_READ; } if (flags & EsOpenWrite) { accessMode |= GENERIC_WRITE; } shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; /* this flag allows files to be deleted/renamed while they are still open, which more in line with unix semantics */ if (OMR_ARE_ALL_BITS_SET(flags, EsOpenShareDelete)) { shareMode = shareMode | FILE_SHARE_DELETE; } if ((flags & EsOpenCreate) == EsOpenCreate) { createMode = OPEN_ALWAYS; } else if ((flags & EsOpenCreateNew) == EsOpenCreateNew) { createMode = CREATE_NEW; } else if ((flags & EsOpenCreateAlways) == EsOpenCreateAlways) { createMode = CREATE_ALWAYS; } else { createMode = OPEN_EXISTING; } flagsAndAttributes = FILE_ATTRIBUTE_NORMAL; if (flags & EsOpenSync) { flagsAndAttributes |= FILE_FLAG_WRITE_THROUGH; } if (flags & EsOpenAsynchronous) { flagsAndAttributes |= FILE_FLAG_OVERLAPPED; } if (flags & EsOpenForInherit) { ZeroMemory(&sAttrib, sizeof(sAttrib)); sAttrib.bInheritHandle = 1; sAttrib.nLength = sizeof(sAttrib); aHandle = CreateFileW(unicodePath, accessMode, shareMode, &sAttrib, createMode, flagsAndAttributes, NULL); } else { aHandle = CreateFileW(unicodePath, accessMode, shareMode, NULL, createMode, flagsAndAttributes, NULL); } if (INVALID_HANDLE_VALUE == aHandle) { error = GetLastError(); portLibrary->error_set_last_error(portLibrary, error, findError(error)); if (unicodeBuffer != unicodePath) { portLibrary->mem_free_memory(portLibrary, unicodePath); } Trc_PRT_file_open_Exception2(path, error, findError(error)); Trc_PRT_file_open_Exit(-1); portLibrary->error_set_last_error(portLibrary, error, findError(error)); return -1; } if ((FILE_TYPE_DISK == GetFileType(aHandle)) && ((flags & EsOpenTruncate) == EsOpenTruncate)) { if (0 == CloseHandle(aHandle)) { error = GetLastError(); portLibrary->error_set_last_error(portLibrary, error, findError(error)); /* continue */ } aHandle = CreateFileW(unicodePath, accessMode, shareMode, NULL, TRUNCATE_EXISTING, flagsAndAttributes, NULL); if (INVALID_HANDLE_VALUE == aHandle) { error = GetLastError(); portLibrary->error_set_last_error(portLibrary, error, findError(error)); if (unicodeBuffer != unicodePath) { portLibrary->mem_free_memory(portLibrary, unicodePath); } Trc_PRT_file_open_Exception3(path, error, findError(error)); Trc_PRT_file_open_Exit(-1); portLibrary->error_set_last_error(portLibrary, error, findError(error)); return -1; } } if (flags & EsOpenAppend) { portLibrary->file_seek(portLibrary, (intptr_t)aHandle, 0, EsSeekEnd); } if (unicodeBuffer != unicodePath) { portLibrary->mem_free_memory(portLibrary, unicodePath); } Trc_PRT_file_open_Exit(aHandle); return ((intptr_t)aHandle); }
intptr_t omrfile_open(struct OMRPortLibrary *portLibrary, const char *path, int32_t flags, int32_t mode) { struct stat buffer; int32_t fd = 0; int32_t realFlags = EsTranslateOpenFlags(flags); int32_t fdflags; const char *errMsg; Trc_PRT_file_open_Entry(path, flags, mode); if (-1 == realFlags) { Trc_PRT_file_open_Exception1(path, flags); Trc_PRT_file_open_Exit(-1); portLibrary->error_set_last_error(portLibrary, EINVAL, findError(EINVAL)); return -1; } /* The write open system call on a directory path returns different * errors from platform to platform (e.g. AIX and zOS return FILE_EXIST * while Linux returns FILE_ISDIR). As such, if the path is a directory, * we always returns the FILE_ISDIR error even if the operation is not * read only. */ if (0 == stat(path, &buffer)) { if (S_ISDIR(buffer.st_mode)) { Trc_PRT_file_open_Exception4(path); Trc_PRT_file_open_Exit(-1); errMsg = portLibrary->nls_lookup_message(portLibrary, J9NLS_ERROR | J9NLS_DO_NOT_APPEND_NEWLINE, J9NLS_PORT_FILE_OPEN_FILE_IS_DIR, NULL); portLibrary->error_set_last_error_with_message(portLibrary, OMRPORT_ERROR_FILE_ISDIR, errMsg); return -1; } } #ifdef J9ZOS390 /* On zOS use the non-tagging version of atoe_open for VM generated files that are always platform * encoded (EBCDIC), e.g. javacore dumps. See CMVC 199888 */ if (flags & EsOpenCreateNoTag) { fd = atoe_open_notag(path, realFlags, mode); } else { fd = open(path, realFlags, mode); } #else fd = open(path, realFlags, mode); #endif if (-1 == fd) { Trc_PRT_file_open_Exception2(path, errno, findError(errno)); Trc_PRT_file_open_Exit(-1); portLibrary->error_set_last_error(portLibrary, errno, findError(errno)); return -1; } /* PR 95345 - Tag this descriptor as being non-inheritable */ fdflags = fcntl(fd, F_GETFD, 0); fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC); fd += FD_BIAS; Trc_PRT_file_open_Exit(fd); return (intptr_t) fd; }