Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
32288 views
/*1* Copyright (c) 2000, 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 <sys/types.h>30#include <sys/socket.h>31#include <fcntl.h>32#include <sys/uio.h>33#include <unistd.h>34#include <sys/stat.h>35#if defined(__linux__)36#include <linux/fs.h>37#include <sys/ioctl.h>38#endif3940#if defined(_ALLBSD_SOURCE)41#define lseek64 lseek42#define stat64 stat43#define flock64 flock44#define off64_t off_t45#define F_SETLKW64 F_SETLKW46#define F_SETLK64 F_SETLK4748#define pread64 pread49#define pwrite64 pwrite50#define ftruncate64 ftruncate51#define fstat64 fstat5253#define fdatasync fsync54#endif5556#include "jni.h"57#include "jni_util.h"58#include "jvm.h"59#include "jlong.h"60#include "nio.h"61#include "nio_util.h"62#include "sun_nio_ch_FileDispatcherImpl.h"63#include "java_lang_Long.h"6465static int preCloseFD = -1; /* File descriptor to which we dup other fd's66before closing them for real */676869JNIEXPORT void JNICALL70Java_sun_nio_ch_FileDispatcherImpl_init(JNIEnv *env, jclass cl)71{72int sp[2];73if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) {74JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");75return;76}77preCloseFD = sp[0];78close(sp[1]);79}8081JNIEXPORT jint JNICALL82Java_sun_nio_ch_FileDispatcherImpl_read0(JNIEnv *env, jclass clazz,83jobject fdo, jlong address, jint len)84{85jint fd = fdval(env, fdo);86void *buf = (void *)jlong_to_ptr(address);8788return convertReturnVal(env, read(fd, buf, len), JNI_TRUE);89}9091JNIEXPORT jint JNICALL92Java_sun_nio_ch_FileDispatcherImpl_pread0(JNIEnv *env, jclass clazz, jobject fdo,93jlong address, jint len, jlong offset)94{95jint fd = fdval(env, fdo);96void *buf = (void *)jlong_to_ptr(address);9798return convertReturnVal(env, pread64(fd, buf, len, offset), JNI_TRUE);99}100101JNIEXPORT jlong JNICALL102Java_sun_nio_ch_FileDispatcherImpl_readv0(JNIEnv *env, jclass clazz,103jobject fdo, jlong address, jint len)104{105jint fd = fdval(env, fdo);106struct iovec *iov = (struct iovec *)jlong_to_ptr(address);107return convertLongReturnVal(env, readv(fd, iov, len), JNI_TRUE);108}109110JNIEXPORT jint JNICALL111Java_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz,112jobject fdo, jlong address, jint len)113{114jint fd = fdval(env, fdo);115void *buf = (void *)jlong_to_ptr(address);116117return convertReturnVal(env, write(fd, buf, len), JNI_FALSE);118}119120JNIEXPORT jint JNICALL121Java_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,122jlong address, jint len, jlong offset)123{124jint fd = fdval(env, fdo);125void *buf = (void *)jlong_to_ptr(address);126127return convertReturnVal(env, pwrite64(fd, buf, len, offset), JNI_FALSE);128}129130JNIEXPORT jlong JNICALL131Java_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz,132jobject fdo, jlong address, jint len)133{134jint fd = fdval(env, fdo);135struct iovec *iov = (struct iovec *)jlong_to_ptr(address);136return convertLongReturnVal(env, writev(fd, iov, len), JNI_FALSE);137}138139static jlong140handle(JNIEnv *env, jlong rv, char *msg)141{142if (rv >= 0)143return rv;144if (errno == EINTR)145return IOS_INTERRUPTED;146JNU_ThrowIOExceptionWithLastError(env, msg);147return IOS_THROWN;148}149150JNIEXPORT jlong JNICALL151Java_sun_nio_ch_FileDispatcherImpl_seek0(JNIEnv *env, jclass clazz,152jobject fdo, jlong offset)153{154jint fd = fdval(env, fdo);155off64_t result;156if (offset < 0) {157result = lseek64(fd, 0, SEEK_CUR);158} else {159result = lseek64(fd, offset, SEEK_SET);160}161return handle(env, (jlong)result, "lseek64 failed");162}163164JNIEXPORT jint JNICALL165Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,166jobject fdo, jboolean md)167{168jint fd = fdval(env, fdo);169int result = 0;170171if (md == JNI_FALSE) {172result = fdatasync(fd);173} else {174#ifdef _AIX175/* On AIX, calling fsync on a file descriptor that is opened only for176* reading results in an error ("EBADF: The FileDescriptor parameter is177* not a valid file descriptor open for writing.").178* However, at this point it is not possibly anymore to read the179* 'writable' attribute of the corresponding file channel so we have to180* use 'fcntl'.181*/182int getfl = fcntl(fd, F_GETFL);183if (getfl >= 0 && (getfl & O_ACCMODE) == O_RDONLY) {184return 0;185}186#endif187result = fsync(fd);188}189return handle(env, result, "Force failed");190}191192JNIEXPORT jint JNICALL193Java_sun_nio_ch_FileDispatcherImpl_truncate0(JNIEnv *env, jobject this,194jobject fdo, jlong size)195{196return handle(env,197ftruncate64(fdval(env, fdo), size),198"Truncation failed");199}200201JNIEXPORT jlong JNICALL202Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)203{204jint fd = fdval(env, fdo);205struct stat64 fbuf;206207if (fstat64(fd, &fbuf) < 0)208return handle(env, -1, "Size failed");209210#ifdef BLKGETSIZE64211if (S_ISBLK(fbuf.st_mode)) {212uint64_t size;213if (ioctl(fd, BLKGETSIZE64, &size) < 0)214return handle(env, -1, "Size failed");215return (jlong)size;216}217#endif218219return fbuf.st_size;220}221222JNIEXPORT jint JNICALL223Java_sun_nio_ch_FileDispatcherImpl_lock0(JNIEnv *env, jobject this, jobject fdo,224jboolean block, jlong pos, jlong size,225jboolean shared)226{227jint fd = fdval(env, fdo);228jint lockResult = 0;229int cmd = 0;230struct flock64 fl;231232fl.l_whence = SEEK_SET;233if (size == (jlong)java_lang_Long_MAX_VALUE) {234fl.l_len = (off64_t)0;235} else {236fl.l_len = (off64_t)size;237}238fl.l_start = (off64_t)pos;239if (shared == JNI_TRUE) {240fl.l_type = F_RDLCK;241} else {242fl.l_type = F_WRLCK;243}244if (block == JNI_TRUE) {245cmd = F_SETLKW64;246} else {247cmd = F_SETLK64;248}249lockResult = fcntl(fd, cmd, &fl);250if (lockResult < 0) {251if ((cmd == F_SETLK64) && (errno == EAGAIN || errno == EACCES))252return sun_nio_ch_FileDispatcherImpl_NO_LOCK;253if (errno == EINTR)254return sun_nio_ch_FileDispatcherImpl_INTERRUPTED;255JNU_ThrowIOExceptionWithLastError(env, "Lock failed");256}257return 0;258}259260JNIEXPORT void JNICALL261Java_sun_nio_ch_FileDispatcherImpl_release0(JNIEnv *env, jobject this,262jobject fdo, jlong pos, jlong size)263{264jint fd = fdval(env, fdo);265jint lockResult = 0;266struct flock64 fl;267int cmd = F_SETLK64;268269fl.l_whence = SEEK_SET;270if (size == (jlong)java_lang_Long_MAX_VALUE) {271fl.l_len = (off64_t)0;272} else {273fl.l_len = (off64_t)size;274}275fl.l_start = (off64_t)pos;276fl.l_type = F_UNLCK;277lockResult = fcntl(fd, cmd, &fl);278if (lockResult < 0) {279JNU_ThrowIOExceptionWithLastError(env, "Release failed");280}281}282283284static void closeFileDescriptor(JNIEnv *env, int fd) {285if (fd != -1) {286int result = close(fd);287if (result < 0)288JNU_ThrowIOExceptionWithLastError(env, "Close failed");289}290}291292JNIEXPORT void JNICALL293Java_sun_nio_ch_FileDispatcherImpl_close0(JNIEnv *env, jclass clazz, jobject fdo)294{295jint fd = fdval(env, fdo);296closeFileDescriptor(env, fd);297}298299JNIEXPORT void JNICALL300Java_sun_nio_ch_FileDispatcherImpl_preClose0(JNIEnv *env, jclass clazz, jobject fdo)301{302jint fd = fdval(env, fdo);303if (preCloseFD >= 0) {304if (dup2(preCloseFD, fd) < 0)305JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");306}307}308309JNIEXPORT void JNICALL310Java_sun_nio_ch_FileDispatcherImpl_closeIntFD(JNIEnv *env, jclass clazz, jint fd)311{312closeFileDescriptor(env, fd);313}314315316