Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/java/io/io_util_md.c
32287 views
/*1* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#if defined(__linux__)26#define _FILE_OFFSET_BITS 6427#endif2829#include "jni.h"30#include "jni_util.h"31#include "jvm.h"32#include "io_util.h"33#include "io_util_md.h"34#include <string.h>35#include <unistd.h>3637#ifdef __solaris__38#include <sys/filio.h>39#endif4041#if defined(__linux__) || defined(_ALLBSD_SOURCE) || defined(_AIX)42#include <sys/ioctl.h>43#endif4445#ifdef __ANDROID__46#define open64 open47#endif4849#ifdef MACOSX5051#include <CoreFoundation/CoreFoundation.h>5253__private_extern__54jstring newStringPlatform(JNIEnv *env, const char* str)55{56jstring rv = NULL;57CFMutableStringRef csref = CFStringCreateMutable(NULL, 0);58if (csref == NULL) {59JNU_ThrowOutOfMemoryError(env, "native heap");60} else {61CFStringAppendCString(csref, str, kCFStringEncodingUTF8);62CFStringNormalize(csref, kCFStringNormalizationFormC);63int clen = CFStringGetLength(csref);64int ulen = (clen + 1) * 2; // utf16 + zero padding65char* chars = malloc(ulen);66if (chars == NULL) {67CFRelease(csref);68JNU_ThrowOutOfMemoryError(env, "native heap");69} else {70if (CFStringGetCString(csref, chars, ulen, kCFStringEncodingUTF16)) {71rv = (*env)->NewString(env, (jchar*)chars, clen);72}73free(chars);74CFRelease(csref);75}76}77return rv;78}79#endif8081FD82handleOpen(const char *path, int oflag, int mode) {83FD fd;84RESTARTABLE(open64(path, oflag, mode), fd);85if (fd != -1) {86struct stat64 buf64;87int result;88RESTARTABLE(fstat64(fd, &buf64), result);89if (result != -1) {90if (S_ISDIR(buf64.st_mode)) {91close(fd);92errno = EISDIR;93fd = -1;94}95} else {96close(fd);97fd = -1;98}99}100return fd;101}102103void104fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags)105{106WITH_PLATFORM_STRING(env, path, ps) {107FD fd;108109#if defined(__linux__) || defined(_ALLBSD_SOURCE)110/* Remove trailing slashes, since the kernel won't */111char *p = (char *)ps + strlen(ps) - 1;112while ((p > ps) && (*p == '/'))113*p-- = '\0';114#endif115fd = handleOpen(ps, flags, 0666);116if (fd != -1) {117SET_FD(this, fd, fid);118} else {119throwFileNotFoundException(env, path);120}121} END_PLATFORM_STRING(env, ps);122}123124void125fileClose(JNIEnv *env, jobject this, jfieldID fid)126{127FD fd = GET_FD(this, fid);128if (fd == -1) {129return;130}131132/* Set the fd to -1 before closing it so that the timing window133* of other threads using the wrong fd (closed but recycled fd,134* that gets re-opened with some other filename) is reduced.135* Practically the chance of its occurance is low, however, we are136* taking extra precaution over here.137*/138SET_FD(this, -1, fid);139140/*141* Don't close file descriptors 0, 1, or 2. If we close these stream142* then a subsequent file open or socket will use them. Instead we143* just redirect these file descriptors to /dev/null.144*/145if (fd >= STDIN_FILENO && fd <= STDERR_FILENO) {146int devnull = open("/dev/null", O_WRONLY);147if (devnull < 0) {148SET_FD(this, fd, fid); // restore fd149JNU_ThrowIOExceptionWithLastError(env, "open /dev/null failed");150} else {151dup2(devnull, fd);152close(devnull);153}154} else if (close(fd) == -1) {155JNU_ThrowIOExceptionWithLastError(env, "close failed");156}157}158159ssize_t160handleRead(FD fd, void *buf, jint len)161{162ssize_t result;163RESTARTABLE(read(fd, buf, len), result);164return result;165}166167ssize_t168handleWrite(FD fd, const void *buf, jint len)169{170ssize_t result;171RESTARTABLE(write(fd, buf, len), result);172return result;173}174175jint176handleAvailable(FD fd, jlong *pbytes)177{178int mode;179struct stat64 buf64;180jlong size = -1, current = -1;181182int result;183RESTARTABLE(fstat64(fd, &buf64), result);184if (result != -1) {185mode = buf64.st_mode;186if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {187int n;188int result;189RESTARTABLE(ioctl(fd, FIONREAD, &n), result);190if (result >= 0) {191*pbytes = n;192return 1;193}194} else if (S_ISREG(mode)) {195size = buf64.st_size;196}197}198199if ((current = lseek64(fd, 0, SEEK_CUR)) == -1) {200return 0;201}202203if (size < current) {204if ((size = lseek64(fd, 0, SEEK_END)) == -1)205return 0;206else if (lseek64(fd, current, SEEK_SET) == -1)207return 0;208}209210*pbytes = size - current;211return 1;212}213214jint215handleSetLength(FD fd, jlong length)216{217int result;218RESTARTABLE(ftruncate64(fd, length), result);219return result;220}221222size_t223getLastErrorString(char *buf, size_t len)224{225if (errno == 0 || len < 1) return 0;226getErrorString(errno, buf, len);227return strlen(buf);228}229230231