/* * Copyright (c) 1998-2010 Caucho Technology -- all rights reserved * * @author Scott Ferguson */ #ifndef WIN32 #include #include #include #include #include #include #include #include #include #include #include #include #endif #include #include #include #include #include #include #include #include "resin.h" typedef struct mmap_file_t { int fd; void *address; size_t length; } mmap_file_t; /* * JniMemoryMappedFile */ #ifndef WIN32 JNIEXPORT jlong JNICALL Java_com_caucho_vfs_JniMemoryMappedFile_nativeOpen(JNIEnv *env, jobject obj, jbyteArray name, jint name_length, jlong file_length) { char buffer[8192]; int fd; int flags; mmap_file_t *file = 0; void *addr; if (! name || name_length <= 0 || sizeof(buffer) <= name_length || file_length <= 0) { return 0; } get_byte_array_region(env, name, 0, name_length, buffer); buffer[name_length] = 0; #ifdef S_ISDIR /* On Linux, check if the file is a directory first. */ { struct stat st; if (stat(buffer, &st) || S_ISDIR(st.st_mode)) { return 0; } } #endif flags = O_RDWR|O_CREAT; #ifdef O_BINARY flags |= O_BINARY; #endif #ifdef O_LARGEFILE flags |= O_LARGEFILE; #endif fd = open(buffer, flags, 0664); if (fd < 0) { return 0; } /* XXX: protect this */ ftruncate(fd, file_length); addr = mmap(0, file_length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); /* fprintf(stderr, "mmap: %x %p\n", (int) file_length, addr); */ if (! addr) { close(fd); return 0; } file = (mmap_file_t *) malloc(sizeof(mmap_file_t)); if (! file) { close(fd); return 0; } memset(file, 0, sizeof(mmap_file_t)); file->fd = fd; file->address = addr; file->length = file_length; return file; } JNIEXPORT jint JNICALL Java_com_caucho_vfs_JniMemoryMappedFile_nativeClose(JNIEnv *env, jobject obj, jlong v_file) { mmap_file_t *file = (mmap_file_t *) (PTR) v_file; if (file) { int fd = file->fd; void *address = file->address; file->fd = 0; file->address = 0; if (fd > 0) { munmap(address, file->length); close(fd); } free(file); } return 0; } JNIEXPORT jint JNICALL Java_com_caucho_vfs_JniMemoryMappedFile_nativeRead(JNIEnv *env, jobject obj, jlong v_file, jlong pos, jbyteArray buf, jint offset, jint length) { mmap_file_t *file; char *buffer; if (! env || ! v_file || ! buf) return -1; file = (mmap_file_t *) (PTR) v_file; if (offset < 0 || length < 0 || file->length < pos + length) return -1; buffer = file->address; if (! buffer) return -1; (*env)->SetByteArrayRegion(env, buf, offset, length, (void*) (buffer + pos)); /* set_byte_array_region(env, buf, offset, length, buffer + pos); */ return length; } JNIEXPORT jint JNICALL Java_com_caucho_vfs_JniMemoryMappedFile_nativeWrite(JNIEnv *env, jobject obj, jlong v_file, jlong pos, jbyteArray buf, jint offset, jint length) { mmap_file_t *file; char *buffer; if (v_file == 0 || buf == 0) return -1; file = (mmap_file_t *) (PTR) v_file; if (offset < 0 || length < 0 || file->length < offset + length) return -1; buffer = file->address; if (! buffer) return -1; /* fprintf(stderr, "get: %p offset=%d len=%d pos=%d\n", buffer, offset, length, (int) pos); */ get_byte_array_region(env, buf, offset, length, buffer + pos); return length; } #else JNIEXPORT jint JNICALL Java_com_caucho_vfs_JniMemoryMappedFile_nativeOpen(JNIEnv *env, jobject obj, jbyteArray name, jint length) { return -1; } JNIEXPORT jint JNICALL Java_com_caucho_vfs_JniMemoryMappedFile_nativeClose(JNIEnv *env, jobject obj, jlong v_file) { return -1; } JNIEXPORT jint JNICALL Java_com_caucho_vfs_JniMemoryMappedFile_nativeRead(JNIEnv *env, jobject obj, jlong v_file, jlong pos, jbyteArray buf, jint offset, jint length) { return -1; } JNIEXPORT jint JNICALL Java_com_caucho_vfs_JniMemoryMappedFile_nativeWrite(JNIEnv *env, jobject obj, jlong v_file, jlong pos, jbyteArray buf, jint offset, jint length) { return -1; } #endif