Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/java/net/SocketOutputStream.c
32287 views
/*1* Copyright (c) 1997, 2008, 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 "jni_util.h"32#include "jvm.h"33#include "net_util.h"3435#include "java_net_SocketOutputStream.h"3637#define min(a, b) ((a) < (b) ? (a) : (b))3839/*40* SocketOutputStream41*/4243static jfieldID IO_fd_fdID;4445/*46* Class: java_net_SocketOutputStream47* Method: init48* Signature: ()V49*/50JNIEXPORT void JNICALL51Java_java_net_SocketOutputStream_init(JNIEnv *env, jclass cls) {52IO_fd_fdID = NET_GetFileDescriptorID(env);53}5455/*56* Class: java_net_SocketOutputStream57* Method: socketWrite058* Signature: (Ljava/io/FileDescriptor;[BII)V59*/60JNIEXPORT void JNICALL61Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this,62jobject fdObj,63jbyteArray data,64jint off, jint len) {65char *bufP;66char BUF[MAX_BUFFER_LEN];67int buflen;68int fd;6970if (IS_NULL(fdObj)) {71JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");72return;73} else {74fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);75/* Bug 4086704 - If the Socket associated with this file descriptor76* was closed (sysCloseFD), the the file descriptor is set to -1.77*/78if (fd == -1) {79JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");80return;81}8283}8485if (len <= MAX_BUFFER_LEN) {86bufP = BUF;87buflen = MAX_BUFFER_LEN;88} else {89buflen = min(MAX_HEAP_BUFFER_LEN, len);90bufP = (char *)malloc((size_t)buflen);9192/* if heap exhausted resort to stack buffer */93if (bufP == NULL) {94bufP = BUF;95buflen = MAX_BUFFER_LEN;96}97}9899while(len > 0) {100int loff = 0;101int chunkLen = min(buflen, len);102int llen = chunkLen;103(*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP);104105if ((*env)->ExceptionCheck(env)) {106break;107} else {108while(llen > 0) {109int n = NET_Send(fd, bufP + loff, llen, 0);110if (n > 0) {111llen -= n;112loff += n;113continue;114}115if (n == JVM_IO_INTR) {116JNU_ThrowByName(env, "java/io/InterruptedIOException", 0);117} else {118if (errno == ECONNRESET) {119JNU_ThrowByName(env, "sun/net/ConnectionResetException",120"Connection reset");121} else {122NET_ThrowByNameWithLastError(env, "java/net/SocketException",123"Write failed");124}125}126if (bufP != BUF) {127free(bufP);128}129return;130}131len -= chunkLen;132off += chunkLen;133}134}135136if (bufP != BUF) {137free(bufP);138}139}140141142