Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/java/net/SocketInputStream.c
32287 views
/*1* Copyright (c) 1997, 2016, 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 <stdlib.h>26#include <errno.h>27#include <string.h>28#include <sys/types.h>29#include <sys/socket.h>3031#include "jvm.h"32#include "jni_util.h"33#include "net_util.h"3435#include "java_net_SocketInputStream.h"363738/************************************************************************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#if !defined(__solaris__)55static int NET_ReadWithTimeout(JNIEnv *env, int fd, char *bufP, int len, long timeout) {56int result = 0;57long prevtime = NET_GetCurrentTime(), newtime;58while (timeout > 0) {59result = NET_TimeoutWithCurrentTime(fd, timeout, prevtime);60if (result <= 0) {61if (result == 0) {62JNU_ThrowByName(env, "java/net/SocketTimeoutException", "Read timed out");63} else if (result == -1) {64if (errno == EBADF) {65JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");66} else if (errno == ENOMEM) {67JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");68} else {69JNU_ThrowByNameWithMessageAndLastError70(env, "java/net/SocketException", "select/poll failed");71}72}73return -1;74}75result = NET_NonBlockingRead(fd, bufP, len);76if (result == -1 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {77newtime = NET_GetCurrentTime();78timeout -= newtime - prevtime;79if (timeout > 0) {80prevtime = newtime;81}82} else {83break;84}85}86return result;87}88#endif8990/*91* Class: java_net_SocketInputStream92* Method: socketRead093* Signature: (Ljava/io/FileDescriptor;[BIII)I94*/95JNIEXPORT jint JNICALL96Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this,97jobject fdObj, jbyteArray data,98jint off, jint len, jint timeout)99{100char BUF[MAX_BUFFER_LEN];101char *bufP;102jint fd, nread;103104if (IS_NULL(fdObj)) {105/* shouldn't this be a NullPointerException? -br */106JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",107"Socket closed");108return -1;109} else {110fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);111/* Bug 4086704 - If the Socket associated with this file descriptor112* was closed (sysCloseFD), then the file descriptor is set to -1.113*/114if (fd == -1) {115JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");116return -1;117}118}119120/*121* If the read is greater than our stack allocated buffer then122* we allocate from the heap (up to a limit)123*/124if (len > MAX_BUFFER_LEN) {125if (len > MAX_HEAP_BUFFER_LEN) {126len = MAX_HEAP_BUFFER_LEN;127}128bufP = (char *)malloc((size_t)len);129if (bufP == NULL) {130bufP = BUF;131len = MAX_BUFFER_LEN;132}133} else {134bufP = BUF;135}136137#if defined(__solaris__)138if (timeout) {139nread = NET_Timeout(fd, timeout);140if (nread <= 0) {141if (nread == 0) {142JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",143"Read timed out");144} else if (nread == JVM_IO_ERR) {145if (errno == EBADF) {146JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");147} else if (errno == ENOMEM) {148JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");149} else {150NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",151"select/poll failed");152}153} else if (nread == JVM_IO_INTR) {154JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",155"Operation interrupted");156}157if (bufP != BUF) {158free(bufP);159}160return -1;161}162}163164nread = NET_Read(fd, bufP, len);165#else166if (timeout) {167nread = NET_ReadWithTimeout(env, fd, bufP, len, timeout);168if ((*env)->ExceptionCheck(env)) {169if (bufP != BUF) {170free(bufP);171}172return nread;173}174} else {175nread = NET_Read(fd, bufP, len);176}177#endif178if (nread <= 0) {179if (nread < 0) {180181switch (errno) {182case ECONNRESET:183case EPIPE:184JNU_ThrowByName(env, "sun/net/ConnectionResetException",185"Connection reset");186break;187188case EBADF:189JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",190"Socket closed");191break;192193case EINTR:194JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",195"Operation interrupted");196break;197198default:199NET_ThrowByNameWithLastError(env,200JNU_JAVANETPKG "SocketException", "Read failed");201}202}203} else {204(*env)->SetByteArrayRegion(env, data, off, nread, (jbyte *)bufP);205}206207if (bufP != BUF) {208free(bufP);209}210return nread;211}212213214