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