bool OsFile_rename(const JvmPathChar *from, const JvmPathChar *to) { const int from_name_len = fn_strlen(from); const int to_name_len = fn_strlen(to); pcsl_string pcsl_filename_from = PCSL_STRING_NULL; pcsl_string pcsl_filename_to = PCSL_STRING_NULL; GUARANTEE(sizeof(jchar) == sizeof(JvmPathChar), "Types must match"); if (pcsl_string_convert_from_utf16(from, from_name_len, &pcsl_filename_from) != PCSL_STRING_OK) { return -1; } if (pcsl_string_convert_from_utf16(to, to_name_len, &pcsl_filename_to) != PCSL_STRING_OK) { return -1; } int result = pcsl_file_rename(&pcsl_filename_from, &pcsl_filename_to); pcsl_string_free(&pcsl_filename_from); pcsl_string_free(&pcsl_filename_to); return (result == 0) ? true : false; }
inline ReturnOop ClassPathAccess::open_local_file(PathChar* path_name, Symbol* entry_symbol, const bool is_class_file JVM_TRAPS) { const char separator_char = OsFile_separator_char; int pos = fn_strlen(path_name); path_name[pos++] = (PathChar)separator_char; for (int i=0; i<entry_symbol->length(); i++) { path_name[pos++] = (PathChar)entry_symbol->byte_at(i); } path_name[pos] = 0; if (is_class_file) { fn_strcat(path_name, FilePath::classfile_suffix); } if (separator_char != '/') { for(PathChar* tf = path_name; *tf; tf++) { if (*tf == (PathChar)'/') { *tf = (PathChar)separator_char; } } } OsFile_Handle handle = OsFile_open(path_name, "rb"); if (handle == NULL) { return NULL; } int size = OsFile_length(handle); return FileDecoder::allocate(handle, 0, size, MUST_CLOSE_FILE JVM_NO_CHECK_AT_BOTTOM); }
extern "C" void fn_strcat(PathChar* s1, const PathChar *s2) { s1 += fn_strlen(s1); while (*s2) { *s1++ = *s2++; } *s1 = 0; }
ReturnOop JarFileParser::get_parser_from_cache(const JvmPathChar* jar_file_name1, TypeArray *jar_file_name2) { // Count trailing zero as well const int name_bytes = jar_file_name1 ? (fn_strlen(jar_file_name1)+1) * sizeof(JvmPathChar) : jar_file_name2->length(); const int max = MAX_CACHED_PARSERS < MaxCachedJarParsers ? MAX_CACHED_PARSERS : MaxCachedJarParsers; #if ENABLE_ISOLATES const char current_task_id = TaskContext::current_task_id(); #endif for( int i=0; i < max; i++ ) { const int ref = _cached_parsers[i]; if (ref >= 0) { #if ENABLE_ISOLATES const char task_id = ObjectHeap::get_global_reference_owner(ref); if( task_id != current_task_id ) { // Don't share cached JarFileParser across task ID. See // JarFileParser.hpp for why. continue; } #endif JarFileParser::Raw parser = ObjectHeap::get_global_ref_object(ref); if (parser.not_null()) { TypeArray::Raw stored_name = parser().pathname(); JvmPathChar *data = (JvmPathChar*)stored_name().byte_base_address(); bool match; if (jar_file_name1) { match = stored_name().length() == name_bytes && jvm_memcmp(data, jar_file_name1, name_bytes) == 0; } else { match = jar_file_name2->equals(&stored_name) || (stored_name().length() == name_bytes && jvm_memcmp(data, jar_file_name2->byte_base_address(), name_bytes) == 0); } if (match) { if (TraceJarCache) { TTY_TRACE(("JAR: parser cache hit: ")); for (int n=0; n <= name_bytes; n++) { TTY_TRACE(("%c", (char)data[n])); } TTY_TRACE_CR(("")); } // Found a match parser().set_timestamp(++_timestamp); return parser; } } } } return NULL; }
// Disabled temporarily - pcsl_file_exist does not distinguish between // directory and "file". bool OsFile_exists(const JvmPathChar *filename) { int name_len = fn_strlen(filename); pcsl_string pcsl_filename = PCSL_STRING_NULL; GUARANTEE(sizeof(jchar) == sizeof(JvmPathChar), "Types must match"); if (pcsl_string_convert_from_utf16(filename, name_len, &pcsl_filename) != PCSL_STRING_OK) { return false; } jboolean result = pcsl_file_exist(&pcsl_filename); pcsl_string_free(&pcsl_filename); return result; }
int OsFile_remove(const JvmPathChar * filename) { int name_len = fn_strlen(filename); pcsl_string pcsl_filename = PCSL_STRING_NULL; GUARANTEE(sizeof(jchar) == sizeof(JvmPathChar), "Types must match"); if (pcsl_string_convert_from_utf16(filename, name_len, &pcsl_filename) != PCSL_STRING_OK) { return -1; } int result = pcsl_file_unlink(&pcsl_filename); pcsl_string_free(&pcsl_filename); return result; }
OsFile_Handle OsFile_open(const JvmPathChar *filename, const char *mode) { int name_len = fn_strlen(filename); pcsl_string pcsl_filename = PCSL_STRING_NULL; GUARANTEE(sizeof(jchar) == sizeof(JvmPathChar), "Types must match"); if (pcsl_string_convert_from_utf16(filename, name_len, &pcsl_filename) != PCSL_STRING_OK) { return NULL; } /* int pcsl_flags = (*mode == 'w') ? (PCSL_FILE_O_CREAT|PCSL_FILE_O_WRONLY| PCSL_FILE_O_TRUNC) : (PCSL_FILE_O_RDONLY); */ int pcsl_flags; if(*mode == 'w') { pcsl_flags = (PCSL_FILE_O_CREAT | PCSL_FILE_O_WRONLY | PCSL_FILE_O_TRUNC); } else if(*mode == 'a') { pcsl_flags = (PCSL_FILE_O_WRONLY | PCSL_FILE_O_APPEND); } else { pcsl_flags = PCSL_FILE_O_RDONLY; } void *pcsl_handle; if (pcsl_file_open(&pcsl_filename, pcsl_flags, &pcsl_handle) == 0) { pcsl_string_free(&pcsl_filename); OsFile_Handle handle = (OsFile_Handle)pcsl_mem_malloc(sizeof(struct _OsFile_Handle)); if (handle) { handle->pcsl_handle = pcsl_handle; } else { pcsl_file_close(pcsl_handle); } return handle; } else { pcsl_string_free(&pcsl_filename); return NULL; } }
// Create or retrieve a JarFileParser for the given JAR file. // As a side effect, it might invalidate any previously obtained // JarFileParser objects by closing their OsFile_handles. ReturnOop JarFileParser::get(const JvmPathChar* jar_file_name1, TypeArray * jar_file_name2, bool enable_entry_cache JVM_TRAPS) { GUARANTEE((jar_file_name1 != NULL && jar_file_name2 == NULL) || (jar_file_name1 == NULL && jar_file_name2 != NULL), "sanity"); UsingFastOops fast_oops; JarFileParser::Fast parser = get_parser_from_cache(jar_file_name1, jar_file_name2); if (parser.not_null()) { return parser; } if (jar_file_name1 && !OsFile_exists(jar_file_name1)) { return NULL; } if (jar_file_name2 && !OsFile_exists((JvmPathChar *)jar_file_name2->byte_base_address())) { return NULL; } parser = Universe::new_mixed_oop(MixedOopDesc::Type_JarFileParser, JarFileParser::allocation_size(), JarFileParser::pointer_count() JVM_CHECK_0); TypeArray::Fast stored_name; if (jar_file_name1 != NULL) { size_t name_bytes = (fn_strlen(jar_file_name1)+1) * sizeof(JvmPathChar); stored_name = Universe::new_byte_array_raw(name_bytes JVM_CHECK_0); JvmPathChar *data = (JvmPathChar *)stored_name().byte_base_address(); jvm_memcpy(data, jar_file_name1, name_bytes); // copy trailing NUL as well. } else { stored_name = jar_file_name2->obj(); } BufferedFile::Fast bf = BufferedFile::allocate(JVM_SINGLE_ARG_CHECK_0); FileDescriptor::Fast desc = FileDescriptor::allocate(JVM_SINGLE_ARG_CHECK_0); OsFile_Handle fh = NULL; for (int pass=0; pass<2; pass++) { if (jar_file_name1) { fh = OsFile_open(jar_file_name1, "rb"); } else { fh = OsFile_open((JvmPathChar *)jar_file_name2->byte_base_address(), "rb"); } if (fh != NULL) { break; } if (pass == 1 && fh == NULL) { // The system is running low on OsFile_Handles. Make sure we flush // the cache, and free all currently cached OsFile_Handles that belong // to other JAR files. flush_caches(); } } if (fh == NULL) { return NULL; } desc().set_handle(fh); bf().set_file_pointer(fh); bf().set_file_size(fh == NULL ? 0 : OsFile_length(fh)); parser().set_file_descriptor(&desc); parser().set_enable_entry_cache(enable_entry_cache); parser().set_pathname(&stored_name); parser().set_buffered_file(&bf); parser().set_timestamp(++_timestamp); if (!parser().find_end_of_central_header()) { // The jar file is corrupted. Stop parsing it. return NULL; } parser().save_parser_in_cache(JVM_SINGLE_ARG_MUST_SUCCEED); return parser; }
OsFile_MappedImageHandle OsFile_MapImage(const PathChar* name, address preferrable_destination, int length, int rw_offset, int rw_length) { GUARANTEE(length == rw_offset + rw_length, "assumption"); GUARANTEE((int(preferrable_destination) % ASSUMED_PAGE_SIZE) == 0, "page aligned"); #if USE_UNICODE_FOR_FILENAMES char ascii_name[256]; int len = fn_strlen(name); if (len > 255) { len = 255; } for (int i=0; i<len; i++) { ascii_name[i] = (char)name[i]; } ascii_name[len] = 0; #else const char *ascii_name = name; #endif Linux_MappedImage *img = (Linux_MappedImage*)jvm_malloc(sizeof(Linux_MappedImage)); if (img == NULL) { return NULL; } if (Verbose) { TTY_TRACE_CR(("Map image desired = 0x%x",int(preferrable_destination))); } int open_flags = O_RDONLY; int fd = jvm_open(ascii_name, open_flags); // Align the RW region down so that the RW region starts at // a page boundary. int ro_length = length - rw_length; ro_length = (int)align_size_down(ro_length, ASSUMED_PAGE_SIZE); rw_offset = ro_length; rw_length = length - ro_length; if (ForceImageRelocation) { // For testing purposes, check relocations preferrable_destination += ASSUMED_PAGE_SIZE * 17; } address ro_addr = (address)-1; address rw_addr = (address)-1; address ro_preferred = preferrable_destination; address rw_preferred = preferrable_destination + rw_offset; if (fd == -1) { goto error; } if (ro_length > 0 && LoadXIPImage && !ForceImageRelocation) { ro_addr = (address)jvm_mmap(ro_preferred, ro_length, PROT_READ, MAP_PRIVATE, fd, 0); rw_addr = (address)jvm_mmap(rw_preferred, rw_length, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, rw_offset); } else { // The whole image needs to be mapped R/W. } if (ro_addr == ro_preferred && rw_preferred == rw_preferred) { if (Verbose) { TTY_TRACE_CR(("Map image actual = 0x%x [RO] size=%d", int(ro_addr), ro_length)); TTY_TRACE_CR(("Map image actual = 0x%x [RW] size=%d", int(rw_addr), rw_length)); } img->mapped_address = ro_addr; img->ro_length = ro_length; img->rw_mapped_address = rw_addr; img->rw_length = rw_length; } else { // Can't get to our preferred location. Relocation of the image content // is needed, so we need to remap the whole thing using RW mapping if (ro_addr != (address) -1) { jvm_munmap(ro_addr, ro_length); } if (rw_addr != (address) -1) { jvm_munmap(rw_addr, rw_length); } ro_addr = (address)jvm_mmap(ro_preferred, length, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (ro_addr == (address)-1) { goto error; } if (Verbose) { TTY_TRACE_CR(("Map image actual = 0x%x [RW] size=%d", int(ro_addr), length)); } img->mapped_address = ro_addr; img->ro_length = length; img->rw_mapped_address = (address)-1; img->rw_length = 0; } // we don't need fd anymore, mapping is still preserved jvm_close(fd); return img; error: if (img) { jvm_free(img); } if (fd >= 0) { jvm_close(fd); } return NULL; }