/* * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #include "jni.h" #include "jni_util.h" #include "jvm.h" #include "io_util.h" #include "io_util_md.h" #include void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) { WITH_PLATFORM_STRING(env, path, ps) { FD fd; #ifdef __linux__ /* Remove trailing slashes, since the kernel won't */ char *p = (char *)ps + strlen(ps) - 1; while ((p > ps) && (*p == '/')) *p-- = '\0'; #endif fd = JVM_Open(ps, flags, 0666); if (fd >= 0) { SET_FD(this, fd, fid); } else { throwFileNotFoundException(env, path); } } END_PLATFORM_STRING(env, ps); } void fileClose(JNIEnv *env, jobject this, jfieldID fid) { FD fd = GET_FD(this, fid); if (fd == -1) { return; } /* Set the fd to -1 before closing it so that the timing window * of other threads using the wrong fd (closed but recycled fd, * that gets re-opened with some other filename) is reduced. * Practically the chance of its occurance is low, however, we are * taking extra precaution over here. */ SET_FD(this, -1, fid); /* * Don't close file descriptors 0, 1, or 2. If we close these stream * then a subsequent file open or socket will use them. Instead we * just redirect these file descriptors to /dev/null. */ if (fd >= STDIN_FILENO && fd <= STDERR_FILENO) { int devnull = open("/dev/null", O_WRONLY); if (devnull < 0) { SET_FD(this, fd, fid); // restore fd JNU_ThrowIOExceptionWithLastError(env, "open /dev/null failed"); } else { dup2(devnull, fd); close(devnull); } } else if (JVM_Close(fd) == -1) { SET_FD(this, fd, fid); // restore fd printf("JVM_Close returned -1\n"); JNU_ThrowIOExceptionWithLastError(env, "close failed"); } } size_t getLastErrorString(char *buf, size_t len) { if (errno == 0 || len < 1) return 0; const char *err = strerror(errno); size_t n = strlen(err); if (n >= len) n = len - 1; strncpy(buf, err, n); buf[n] = '\0'; return n; }