/** * Create a buffered filestream from a portable file descriptor. * * @param[in] portLibrary The port library. * @param[in] fd The file descriptor. * @param[in] flags Open flags * * @return the resulting filestream. On failure, will return NULL. */ OMRFileStream * omrfilestream_fdopen(OMRPortLibrary *portLibrary, intptr_t fd, int32_t flags) { intptr_t fileDescriptor = 0; intptr_t rc = 0; OMRFileStream *fileStream = NULL; const char *realFlags = NULL; Trc_PRT_filestream_fdopen_Entry(fd, flags); /* translate the open flags */ realFlags = EsTranslateOpenFlags(flags); if (NULL == realFlags) { portLibrary->error_set_last_error(portLibrary, EINVAL, findError(EINVAL)); Trc_PRT_filestream_fdopen_invalidArgs(fd, flags); Trc_PRT_filestream_fdopen_Exit(NULL); return NULL; } /* Get the native file descriptor */ fileDescriptor = portLibrary->file_convert_omrfile_fd_to_native_fd(portLibrary, fd); /* Convert the file descriptor to a FILE */ fileStream = fdopen(fileDescriptor, realFlags); if (NULL == fileStream) { rc = portLibrary->error_set_last_error(portLibrary, errno, findError(errno)); Trc_PRT_filestream_fdopen_failed(fd, flags, (int32_t) rc); } Trc_PRT_filestream_fdopen_Exit(fileStream); return fileStream; }
static jint harmony_io_openImpl(JNIEnv* env, jobject, jbyteArray pathByteArray, jint jflags) { int flags = 0; int mode = 0; // BEGIN android-changed // don't want default permissions to allow global access. switch(jflags) { case 0: flags = HyOpenRead; mode = 0; break; case 1: flags = HyOpenCreate | HyOpenWrite | HyOpenTruncate; mode = 0600; break; case 16: flags = HyOpenRead | HyOpenWrite | HyOpenCreate; mode = 0600; break; case 32: flags = HyOpenRead | HyOpenWrite | HyOpenCreate | HyOpenSync; mode = 0600; break; case 256: flags = HyOpenWrite | HyOpenCreate | HyOpenAppend; mode = 0600; break; } // BEGIN android-changed flags = EsTranslateOpenFlags(flags); ScopedByteArray path(env, pathByteArray); jint rc = TEMP_FAILURE_RETRY(open(&path[0], flags, mode)); if (rc == -1) { // Get the human-readable form of errno. char buffer[80]; const char* reason = jniStrError(errno, &buffer[0], sizeof(buffer)); // Construct a message that includes the path and the reason. // (pathByteCount already includes space for our trailing NUL.) size_t pathByteCount = env->GetArrayLength(pathByteArray); LocalArray<128> message(pathByteCount + 2 + strlen(reason) + 1); snprintf(&message[0], message.size(), "%s (%s)", &path[0], reason); // We always throw FileNotFoundException, regardless of the specific // failure. (This appears to be true of the RI too.) jniThrowException(env, "java/io/FileNotFoundException", &message[0]); } return rc; }
/** * Opens a buffered filestream. All filestreams opened this way start fully buffered. * Opening a filestream with EsOpenRead is not supported, and will return an error code. * * @param[in] portLibrary The port library * @param[in] path Name of the file to be opened. * @param[in] flags Portable file read/write attributes. * @param[in] mode Platform file permissions. * * @return The filestream for the newly opened file. NULL on failure. * * @note accesses the "current working directory" property of the process if the path is relative. */ OMRFileStream * omrfilestream_open(struct OMRPortLibrary *portLibrary, const char *path, int32_t flags, int32_t mode) { OMRFileStream *fileStream = NULL; const char *realFlags = NULL; intptr_t file = -1; intptr_t fileDescriptor = -1; Trc_PRT_filestream_open_Entry(path, flags, mode); if (NULL == path) { Trc_PRT_filestream_open_invalidPath(path, flags, mode); portLibrary->error_set_last_error(portLibrary, EINVAL, findError(EINVAL)); Trc_PRT_filestream_open_Exit(NULL); return NULL; } realFlags = EsTranslateOpenFlags(flags); if ((NULL == realFlags) || (EsOpenRead == (flags & EsOpenRead))) { Trc_PRT_filestream_open_invalidOpenFlags(path, flags, mode); portLibrary->error_set_last_error(portLibrary, EINVAL, findError(EINVAL)); Trc_PRT_filestream_open_Exit(NULL); return NULL; } /* Attempt to portably honor the open flags and mode by using the portlibrary */ file = portLibrary->file_open(portLibrary, path, flags, mode); if (-1 == file) { int32_t error = portLibrary->error_last_error_number(portLibrary); Trc_PRT_filestream_open_failedToOpen(path, flags, mode, error); Trc_PRT_filestream_open_Exit(NULL); return NULL; } /* Get the native file descriptor */ fileDescriptor = portLibrary->file_convert_omrfile_fd_to_native_fd(portLibrary, file); /* Convert the file to a fileDescriptor */ fileStream = fdopen(fileDescriptor, realFlags); if (NULL == fileStream) { int savedErrno = errno; portLibrary->file_close(portLibrary, file); Trc_PRT_filestream_open_fdopenFailed(path, flags, mode, findError(savedErrno)); portLibrary->error_set_last_error(portLibrary, savedErrno, findError(savedErrno)); } Trc_PRT_filestream_open_Exit(fileStream); return fileStream; }
IDATA hyfile_open (const char *path, I_32 flags, I_32 mode) { struct stat buffer; I_32 fd; I_32 realFlags = EsTranslateOpenFlags (flags); I_32 fdflags; // Trc_PRT_file_open_Entry (path, flags, mode); if (realFlags == -1) { // Trc_PRT_file_open_Exit1 (flags); hyerror_set_last_error(EINVAL, findError(EINVAL)); return -1; } if ( ( flags&HyOpenRead && !(flags&HyOpenWrite) ) && !stat (path, &buffer)) { if (S_ISDIR (buffer.st_mode)) { hyerror_set_last_error_with_message(findError(EEXIST), "Is a directory"); // Trc_PRT_file_open_Exit4 (); return -1; } } fd = open (path, realFlags, mode); if (-1 == fd) { // Trc_PRT_file_open_Exit2 (errno, findError (errno)); int rc = errno; hyerror_set_last_error(rc, findError(rc)); return -1; } /* 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 (IDATA) fd; }
static jint OSFileSystem_openImpl(JNIEnv * env, jobject obj, jbyteArray path, jint jflags) { TRACE; int flags = 0; int mode = 0; jint * portFD; jsize length; char pathCopy[HyMaxPath]; // BEGIN android-changed // don't want default permissions to allow global access. switch(jflags) { case 0: flags = HyOpenRead; mode = 0; break; case 1: flags = HyOpenCreate | HyOpenWrite | HyOpenTruncate; mode = 0600; break; case 16: flags = HyOpenRead | HyOpenWrite | HyOpenCreate; mode = 0600; break; case 32: flags = HyOpenRead | HyOpenWrite | HyOpenCreate | HyOpenSync; mode = 0600; break; case 256: flags = HyOpenWrite | HyOpenCreate | HyOpenAppend; mode = 0600; break; } // BEGIN android-changed flags = EsTranslateOpenFlags(flags); length = env->GetArrayLength (path); length = length < HyMaxPath - 1 ? length : HyMaxPath - 1; env->GetByteArrayRegion (path, 0, length, (jbyte *)pathCopy); pathCopy[length] = '\0'; convertToPlatform (pathCopy); int cc; if(pathCopy == NULL) { jniThrowException(env, "java/lang/NullPointerException", NULL); return -1; } do { cc = ::open(pathCopy, flags, mode); } while(cc < 0 && errno == EINTR); if(cc < 0 && errno > 0) { cc = -errno; } DBG("return fd=%d", cc); return cc; }
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; }