Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/native/java/net/SocketInputStream.c
32287 views
/*1* Copyright (c) 1997, 2013, 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 <winsock2.h>27#include <ctype.h>28#include <stdio.h>29#include <stdlib.h>30#include <malloc.h>31#include <sys/types.h>3233#include "java_net_SocketInputStream.h"3435#include "net_util.h"36#include "jni_util.h"3738/*************************************************************************39* SocketInputStream40*/4142static jfieldID IO_fd_fdID;4344/*45* Class: java_net_SocketInputStream46* Method: init47* Signature: ()V48*/49JNIEXPORT void JNICALL50Java_java_net_SocketInputStream_init(JNIEnv *env, jclass cls) {51IO_fd_fdID = NET_GetFileDescriptorID(env);52}5354/*55* Class: java_net_SocketInputStream56* Method: socketRead57* Signature: (Ljava/io/FileDescriptor;[BIII)I58*/59JNIEXPORT jint JNICALL60Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this,61jobject fdObj, jbyteArray data,62jint off, jint len, jint timeout)63{64char *bufP;65char BUF[MAX_BUFFER_LEN];66jint fd, newfd;67jint nread;6869if (IS_NULL(fdObj)) {70JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");71return -1;72}73fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);74if (fd == -1) {75NET_ThrowSocketException(env, "Socket closed");76return -1;77}7879/*80* If the caller buffer is large than our stack buffer then we allocate81* from the heap (up to a limit). If memory is exhausted we always use82* the stack buffer.83*/84if (len <= MAX_BUFFER_LEN) {85bufP = BUF;86} else {87if (len > MAX_HEAP_BUFFER_LEN) {88len = MAX_HEAP_BUFFER_LEN;89}90bufP = (char *)malloc((size_t)len);91if (bufP == NULL) {92/* allocation failed so use stack buffer */93bufP = BUF;94len = MAX_BUFFER_LEN;95}96}979899if (timeout) {100if (timeout <= 5000 || !isRcvTimeoutSupported) {101int ret = NET_Timeout (fd, timeout);102103if (ret <= 0) {104if (ret == 0) {105JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",106"Read timed out");107} else if (ret == JVM_IO_ERR) {108JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");109} else if (ret == JVM_IO_INTR) {110JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",111"Operation interrupted");112}113if (bufP != BUF) {114free(bufP);115}116return -1;117}118119/*check if the socket has been closed while we were in timeout*/120newfd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);121if (newfd == -1) {122NET_ThrowSocketException(env, "Socket Closed");123if (bufP != BUF) {124free(bufP);125}126return -1;127}128}129}130131nread = recv(fd, bufP, len, 0);132if (nread > 0) {133(*env)->SetByteArrayRegion(env, data, off, nread, (jbyte *)bufP);134} else {135if (nread < 0) {136int err = WSAGetLastError();137// Check if the socket has been closed since we last checked.138// This could be a reason for recv failing.139if ((*env)->GetIntField(env, fdObj, IO_fd_fdID) == -1) {140NET_ThrowSocketException(env, "Socket closed");141} else {142switch (err) {143case WSAEINTR:144JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",145"socket closed");146break;147148case WSAECONNRESET:149case WSAESHUTDOWN:150/*151* Connection has been reset - Windows sometimes reports152* the reset as a shutdown error.153*/154JNU_ThrowByName(env, "sun/net/ConnectionResetException",155"");156break;157158case WSAETIMEDOUT :159JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",160"Read timed out");161break;162163default:164NET_ThrowCurrent(env, "recv failed");165}166}167}168}169if (bufP != BUF) {170free(bufP);171}172return nread;173}174175176