RHO_GLOBAL int open(const char *path, int oflag, ...) { std::string fpath; if (path) fpath = path; if (fpath.empty()) { RHO_LOG("open: path is empty"); errno = EFAULT; return -1; } RHO_LOG("open: %s...", path); fpath = make_full_path(fpath); //RHO_LOG("open: %s: fpath: %s", path, fpath.c_str()); bool java_way = need_java_way(fpath); if (java_way && has_pending_exception()) { errno = EFAULT; return -1; } if (java_way && (oflag & (O_WRONLY | O_RDWR))) { //RHO_LOG("open: %s: copy from Android package", path); JNIEnv *env = jnienv(); jstring relPathObj = rho_cast<jstring>(env, make_rel_path(fpath).c_str()); env->CallStaticBooleanMethod(clsFileApi, midCopy, relPathObj); env->DeleteLocalRef(relPathObj); if (has_pending_exception()) { errno = EFAULT; return -1; } java_way = false; } int fd; if (java_way) { JNIEnv *env = jnienv(); jstring relPathObj = rho_cast<jstring>(env, make_rel_path(fpath).c_str()); jobject is = env->CallStaticObjectMethod(clsFileApi, midOpen, relPathObj); env->DeleteLocalRef(relPathObj); if (is != NULL) { scoped_lock_t guard(rho_fd_mtx); if (!rho_fd_free.empty()) { fd = rho_fd_free[0]; rho_fd_free.erase(rho_fd_free.begin()); } else fd = rho_fd_counter++; rho_fd_data_t d; d.is = env->NewGlobalRef(is); d.fpath = fpath; d.pos = 0; rho_fd_map[fd] = d; } else { errno = EFAULT; fd = -1; } env->DeleteLocalRef(is); } else { mode_t mode = 0; if (oflag & O_CREAT) { va_list vl; va_start(vl, oflag); mode = va_arg(vl, int); va_end(vl); } fd = real_open(path, oflag, mode); }
RHO_GLOBAL int open(const char *path, int oflag, ...) { std::string fpath; if (path) fpath = path; if (fpath.empty()) { RHO_LOG("open: path is empty"); errno = EFAULT; return -1; } RHO_LOG("open: %s...", path); fpath = make_full_path(fpath); RHO_LOG("open: %s: fpath: %s", path, fpath.c_str()); bool emulate = need_emulate(fpath); RHO_LOG("open: %s: emulate: %d", path, (int)emulate); if (emulate && has_pending_exception()) { RHO_LOG("open: %s: has_pending_exception, return -1", path); errno = EFAULT; return -1; } if (emulate && (oflag & (O_WRONLY | O_RDWR))) { RHO_LOG("open: %s: copy from Android package", path); JNIEnv *env = jnienv(); jhstring relPathObj = rho_cast<jhstring>(env, make_rel_path(fpath).c_str()); env->CallStaticBooleanMethod(clsFileApi, midCopy, relPathObj.get()); if (has_pending_exception()) { RHO_LOG("open: %s: has_pending_exception, return -1", path); errno = EFAULT; return -1; } emulate = false; } RHO_LOG("open: %s: emulate: %d", path, (int)emulate); int fd; if (emulate) { RHO_LOG("open: %s: emulate", path); JNIEnv *env = jnienv(); jhstring relPathObj = rho_cast<jhstring>(env, make_rel_path(fpath).c_str()); jhobject is = jhobject(env->CallStaticObjectMethod(clsFileApi, midOpen, relPathObj.get())); if (!is) { errno = EFAULT; fd = -1; } else { scoped_lock_t guard(rho_file_mtx); if (!rho_fd_free.empty()) { fd = rho_fd_free[0]; rho_fd_free.erase(rho_fd_free.begin()); } else fd = rho_fd_counter++; rho_fd_data_t d; d.type = rho_type_file; d.is = env->NewGlobalRef(is.get()); d.dirp = NULL; d.fpath = fpath; d.pos = 0; rho_fd_map[fd] = d; } } else { RHO_LOG("open: %s: native", path); mode_t mode = 0; if (oflag & O_CREAT) { va_list vl; va_start(vl, oflag); mode = va_arg(vl, int); va_end(vl); } fd = real_open(path, oflag, mode); }