Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/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#include <windows.h>26#include "jni.h"27#include "jni_util.h"28#include "jvm.h"29#include "jlong.h"30#include "sun_nio_ch_FileDispatcherImpl.h"31#include <io.h>32#include "nio.h"33#include "nio_util.h"34#include "jlong.h"353637/**************************************************************38* FileDispatcherImpl.c39*/4041JNIEXPORT jint JNICALL42Java_sun_nio_ch_FileDispatcherImpl_read0(JNIEnv *env, jclass clazz, jobject fdo,43jlong address, jint len)44{45DWORD read = 0;46BOOL result = 0;47HANDLE h = (HANDLE)(handleval(env, fdo));4849if (h == INVALID_HANDLE_VALUE) {50JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");51return IOS_THROWN;52}53result = ReadFile(h, /* File handle to read */54(LPVOID)address, /* address to put data */55len, /* number of bytes to read */56&read, /* number of bytes read */57NULL); /* no overlapped struct */58if (result == 0) {59int error = GetLastError();60if (error == ERROR_BROKEN_PIPE) {61return IOS_EOF;62}63if (error == ERROR_NO_DATA) {64return IOS_UNAVAILABLE;65}66JNU_ThrowIOExceptionWithLastError(env, "Read failed");67return IOS_THROWN;68}69return convertReturnVal(env, (jint)read, JNI_TRUE);70}7172JNIEXPORT jlong JNICALL73Java_sun_nio_ch_FileDispatcherImpl_readv0(JNIEnv *env, jclass clazz, jobject fdo,74jlong address, jint len)75{76DWORD read = 0;77BOOL result = 0;78jlong totalRead = 0;79LPVOID loc;80int i = 0;81DWORD num = 0;82struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address);83HANDLE h = (HANDLE)(handleval(env, fdo));8485if (h == INVALID_HANDLE_VALUE) {86JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");87return IOS_THROWN;88}8990for(i=0; i<len; i++) {91loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base);92num = iovecp[i].iov_len;93result = ReadFile(h, /* File handle to read */94loc, /* address to put data */95num, /* number of bytes to read */96&read, /* number of bytes read */97NULL); /* no overlapped struct */98if (read > 0) {99totalRead += read;100}101if (read < num) {102break;103}104}105106if (result == 0) {107int error = GetLastError();108if (error == ERROR_BROKEN_PIPE) {109return IOS_EOF;110}111if (error == ERROR_NO_DATA) {112return IOS_UNAVAILABLE;113}114JNU_ThrowIOExceptionWithLastError(env, "Read failed");115return IOS_THROWN;116}117118return convertLongReturnVal(env, totalRead, JNI_TRUE);119}120121JNIEXPORT jint JNICALL122Java_sun_nio_ch_FileDispatcherImpl_pread0(JNIEnv *env, jclass clazz, jobject fdo,123jlong address, jint len, jlong offset)124{125DWORD read = 0;126BOOL result = 0;127HANDLE h = (HANDLE)(handleval(env, fdo));128DWORD lowPos = 0;129long highPos = 0;130DWORD lowOffset = 0;131long highOffset = 0;132133if (h == INVALID_HANDLE_VALUE) {134JNU_ThrowIOExceptionWithLastError(env, "Invalid handle");135return IOS_THROWN;136}137138lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT);139if (lowPos == ((DWORD)-1)) {140if (GetLastError() != ERROR_SUCCESS) {141JNU_ThrowIOExceptionWithLastError(env, "Seek failed");142return IOS_THROWN;143}144}145146lowOffset = (DWORD)offset;147highOffset = (DWORD)(offset >> 32);148lowOffset = SetFilePointer(h, lowOffset, &highOffset, FILE_BEGIN);149if (lowOffset == ((DWORD)-1)) {150if (GetLastError() != ERROR_SUCCESS) {151JNU_ThrowIOExceptionWithLastError(env, "Seek failed");152return IOS_THROWN;153}154}155156result = ReadFile(h, /* File handle to read */157(LPVOID)address, /* address to put data */158len, /* number of bytes to read */159&read, /* number of bytes read */160NULL); /* struct with offset */161162if (result == 0) {163int error = GetLastError();164if (error == ERROR_BROKEN_PIPE) {165return IOS_EOF;166}167if (error == ERROR_NO_DATA) {168return IOS_UNAVAILABLE;169}170JNU_ThrowIOExceptionWithLastError(env, "Read failed");171return IOS_THROWN;172}173174lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN);175if (lowPos == ((DWORD)-1)) {176if (GetLastError() != ERROR_SUCCESS) {177JNU_ThrowIOExceptionWithLastError(env, "Seek failed");178return IOS_THROWN;179}180}181return convertReturnVal(env, (jint)read, JNI_TRUE);182}183184JNIEXPORT jint JNICALL185Java_sun_nio_ch_FileDispatcherImpl_write0(JNIEnv *env, jclass clazz, jobject fdo,186jlong address, jint len, jboolean append)187{188BOOL result = 0;189DWORD written = 0;190HANDLE h = (HANDLE)(handleval(env, fdo));191192if (h != INVALID_HANDLE_VALUE) {193OVERLAPPED ov;194LPOVERLAPPED lpOv;195if (append == JNI_TRUE) {196ov.Offset = (DWORD)0xFFFFFFFF;197ov.OffsetHigh = (DWORD)0xFFFFFFFF;198ov.hEvent = NULL;199lpOv = &ov;200} else {201lpOv = NULL;202}203result = WriteFile(h, /* File handle to write */204(LPCVOID)address, /* pointers to the buffers */205len, /* number of bytes to write */206&written, /* receives number of bytes written */207lpOv); /* overlapped struct */208}209210if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {211JNU_ThrowIOExceptionWithLastError(env, "Write failed");212return IOS_THROWN;213}214215return convertReturnVal(env, (jint)written, JNI_FALSE);216}217218JNIEXPORT jlong JNICALL219Java_sun_nio_ch_FileDispatcherImpl_writev0(JNIEnv *env, jclass clazz, jobject fdo,220jlong address, jint len, jboolean append)221{222BOOL result = 0;223DWORD written = 0;224HANDLE h = (HANDLE)(handleval(env, fdo));225jlong totalWritten = 0;226227if (h != INVALID_HANDLE_VALUE) {228LPVOID loc;229int i = 0;230DWORD num = 0;231struct iovec *iovecp = (struct iovec *)jlong_to_ptr(address);232OVERLAPPED ov;233LPOVERLAPPED lpOv;234if (append == JNI_TRUE) {235ov.Offset = (DWORD)0xFFFFFFFF;236ov.OffsetHigh = (DWORD)0xFFFFFFFF;237ov.hEvent = NULL;238lpOv = &ov;239} else {240lpOv = NULL;241}242for(i=0; i<len; i++) {243loc = (LPVOID)jlong_to_ptr(iovecp[i].iov_base);244num = iovecp[i].iov_len;245result = WriteFile(h, /* File handle to write */246loc, /* pointers to the buffers */247num, /* number of bytes to write */248&written,/* receives number of bytes written */249lpOv); /* overlapped struct */250if (written > 0) {251totalWritten += written;252}253if (written < num) {254break;255}256}257}258259if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {260JNU_ThrowIOExceptionWithLastError(env, "Write failed");261return IOS_THROWN;262}263264return convertLongReturnVal(env, totalWritten, JNI_FALSE);265}266267JNIEXPORT jint JNICALL268Java_sun_nio_ch_FileDispatcherImpl_pwrite0(JNIEnv *env, jclass clazz, jobject fdo,269jlong address, jint len, jlong offset)270{271BOOL result = 0;272DWORD written = 0;273HANDLE h = (HANDLE)(handleval(env, fdo));274DWORD lowPos = 0;275long highPos = 0;276DWORD lowOffset = 0;277long highOffset = 0;278279lowPos = SetFilePointer(h, 0, &highPos, FILE_CURRENT);280if (lowPos == ((DWORD)-1)) {281if (GetLastError() != ERROR_SUCCESS) {282JNU_ThrowIOExceptionWithLastError(env, "Seek failed");283return IOS_THROWN;284}285}286287lowOffset = (DWORD)offset;288highOffset = (DWORD)(offset >> 32);289lowOffset = SetFilePointer(h, lowOffset, &highOffset, FILE_BEGIN);290if (lowOffset == ((DWORD)-1)) {291if (GetLastError() != ERROR_SUCCESS) {292JNU_ThrowIOExceptionWithLastError(env, "Seek failed");293return IOS_THROWN;294}295}296297result = WriteFile(h, /* File handle to write */298(LPCVOID)address, /* pointers to the buffers */299len, /* number of bytes to write */300&written, /* receives number of bytes written */301NULL); /* no overlapped struct */302303if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {304JNU_ThrowIOExceptionWithLastError(env, "Write failed");305return IOS_THROWN;306}307308lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN);309if (lowPos == ((DWORD)-1)) {310if (GetLastError() != ERROR_SUCCESS) {311JNU_ThrowIOExceptionWithLastError(env, "Seek failed");312return IOS_THROWN;313}314}315316return convertReturnVal(env, (jint)written, JNI_FALSE);317}318319JNIEXPORT jlong JNICALL320Java_sun_nio_ch_FileDispatcherImpl_seek0(JNIEnv *env, jclass clazz,321jobject fdo, jlong offset)322{323BOOL result = 0;324HANDLE h = (HANDLE)(handleval(env, fdo));325LARGE_INTEGER where;326DWORD whence;327328if (offset < 0) {329where.QuadPart = 0;330whence = FILE_CURRENT;331} else {332where.QuadPart = offset;333whence = FILE_BEGIN;334}335336result = SetFilePointerEx(h, where, &where, whence);337if (result == 0) {338JNU_ThrowIOExceptionWithLastError(env, "SetFilePointerEx failed");339return IOS_THROWN;340}341return (jlong)where.QuadPart;342}343344JNIEXPORT jint JNICALL345Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,346jobject fdo, jboolean md)347{348int result = 0;349HANDLE h = (HANDLE)(handleval(env, fdo));350351if (h != INVALID_HANDLE_VALUE) {352result = FlushFileBuffers(h);353if (result == 0) {354int error = GetLastError();355if (error != ERROR_ACCESS_DENIED) {356JNU_ThrowIOExceptionWithLastError(env, "Force failed");357return IOS_THROWN;358}359}360} else {361JNU_ThrowIOExceptionWithLastError(env, "Force failed");362return IOS_THROWN;363}364return 0;365}366367JNIEXPORT jint JNICALL368Java_sun_nio_ch_FileDispatcherImpl_truncate0(JNIEnv *env, jobject this,369jobject fdo, jlong size)370{371DWORD lowPos = 0;372long highPos = 0;373BOOL result = 0;374HANDLE h = (HANDLE)(handleval(env, fdo));375376lowPos = (DWORD)size;377highPos = (long)(size >> 32);378lowPos = SetFilePointer(h, lowPos, &highPos, FILE_BEGIN);379if (lowPos == ((DWORD)-1)) {380if (GetLastError() != ERROR_SUCCESS) {381JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");382return IOS_THROWN;383}384}385result = SetEndOfFile(h);386if (result == 0) {387JNU_ThrowIOExceptionWithLastError(env, "Truncation failed");388return IOS_THROWN;389}390return 0;391}392393JNIEXPORT jlong JNICALL394Java_sun_nio_ch_FileDispatcherImpl_size0(JNIEnv *env, jobject this, jobject fdo)395{396DWORD sizeLow = 0;397DWORD sizeHigh = 0;398HANDLE h = (HANDLE)(handleval(env, fdo));399400sizeLow = GetFileSize(h, &sizeHigh);401if (sizeLow == ((DWORD)-1)) {402if (GetLastError() != ERROR_SUCCESS) {403JNU_ThrowIOExceptionWithLastError(env, "Size failed");404return IOS_THROWN;405}406}407return (((jlong)sizeHigh) << 32) | sizeLow;408}409410JNIEXPORT jint JNICALL411Java_sun_nio_ch_FileDispatcherImpl_lock0(JNIEnv *env, jobject this, jobject fdo,412jboolean block, jlong pos, jlong size,413jboolean shared)414{415HANDLE h = (HANDLE)(handleval(env, fdo));416DWORD lowPos = (DWORD)pos;417long highPos = (long)(pos >> 32);418DWORD lowNumBytes = (DWORD)size;419DWORD highNumBytes = (DWORD)(size >> 32);420BOOL result;421DWORD flags = 0;422OVERLAPPED o;423o.hEvent = 0;424o.Offset = lowPos;425o.OffsetHigh = highPos;426if (block == JNI_FALSE) {427flags |= LOCKFILE_FAIL_IMMEDIATELY;428}429if (shared == JNI_FALSE) {430flags |= LOCKFILE_EXCLUSIVE_LOCK;431}432result = LockFileEx(h, flags, 0, lowNumBytes, highNumBytes, &o);433if (result == 0) {434int error = GetLastError();435if (error != ERROR_LOCK_VIOLATION) {436JNU_ThrowIOExceptionWithLastError(env, "Lock failed");437return sun_nio_ch_FileDispatcherImpl_NO_LOCK;438}439if (flags & LOCKFILE_FAIL_IMMEDIATELY) {440return sun_nio_ch_FileDispatcherImpl_NO_LOCK;441}442JNU_ThrowIOExceptionWithLastError(env, "Lock failed");443return sun_nio_ch_FileDispatcherImpl_NO_LOCK;444}445return sun_nio_ch_FileDispatcherImpl_LOCKED;446}447448JNIEXPORT void JNICALL449Java_sun_nio_ch_FileDispatcherImpl_release0(JNIEnv *env, jobject this,450jobject fdo, jlong pos, jlong size)451{452HANDLE h = (HANDLE)(handleval(env, fdo));453DWORD lowPos = (DWORD)pos;454long highPos = (long)(pos >> 32);455DWORD lowNumBytes = (DWORD)size;456DWORD highNumBytes = (DWORD)(size >> 32);457jint result = 0;458OVERLAPPED o;459o.hEvent = 0;460o.Offset = lowPos;461o.OffsetHigh = highPos;462result = UnlockFileEx(h, 0, lowNumBytes, highNumBytes, &o);463if (result == 0 && GetLastError() != ERROR_NOT_LOCKED) {464JNU_ThrowIOExceptionWithLastError(env, "Release failed");465}466}467468static void closeFile(JNIEnv *env, jlong fd) {469HANDLE h = (HANDLE)fd;470if (h != INVALID_HANDLE_VALUE) {471int result = CloseHandle(h);472if (result < 0)473JNU_ThrowIOExceptionWithLastError(env, "Close failed");474}475}476477JNIEXPORT void JNICALL478Java_sun_nio_ch_FileDispatcherImpl_close0(JNIEnv *env, jclass clazz, jobject fdo)479{480jlong fd = handleval(env, fdo);481closeFile(env, fd);482}483484JNIEXPORT void JNICALL485Java_sun_nio_ch_FileDispatcherImpl_closeByHandle(JNIEnv *env, jclass clazz,486jlong fd)487{488closeFile(env, fd);489}490491JNIEXPORT jlong JNICALL492Java_sun_nio_ch_FileDispatcherImpl_duplicateHandle(JNIEnv *env, jclass this, jlong handle)493{494HANDLE hProcess = GetCurrentProcess();495HANDLE hFile = jlong_to_ptr(handle);496HANDLE hResult;497BOOL res = DuplicateHandle(hProcess, hFile, hProcess, &hResult, 0, FALSE,498DUPLICATE_SAME_ACCESS);499if (res == 0)500JNU_ThrowIOExceptionWithLastError(env, "DuplicateHandle failed");501return ptr_to_jlong(hResult);502}503504505