Path: blob/master/src/java.base/unix/native/libnet/SocketOutputStream.c
41119 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*/24#include <errno.h>25#include <stdlib.h>26#include <string.h>2728#include "net_util.h"2930#include "java_net_SocketOutputStream.h"3132#define min(a, b) ((a) < (b) ? (a) : (b))3334/*35* SocketOutputStream36*/3738static jfieldID IO_fd_fdID;3940/*41* Class: java_net_SocketOutputStream42* Method: init43* Signature: ()V44*/45JNIEXPORT void JNICALL46Java_java_net_SocketOutputStream_init(JNIEnv *env, jclass cls) {47IO_fd_fdID = NET_GetFileDescriptorID(env);48}4950/*51* Class: java_net_SocketOutputStream52* Method: socketWrite053* Signature: (Ljava/io/FileDescriptor;[BII)V54*/55JNIEXPORT void JNICALL56Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this,57jobject fdObj,58jbyteArray data,59jint off, jint len) {60char *bufP;61char BUF[MAX_BUFFER_LEN];62int buflen;63int fd;6465if (IS_NULL(fdObj)) {66JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");67return;68} else {69fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);70/* Bug 4086704 - If the Socket associated with this file descriptor71* was closed (sysCloseFD), the file descriptor is set to -1.72*/73if (fd == -1) {74JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");75return;76}7778}7980if (len <= MAX_BUFFER_LEN) {81bufP = BUF;82buflen = MAX_BUFFER_LEN;83} else {84buflen = min(MAX_HEAP_BUFFER_LEN, len);85bufP = (char *)malloc((size_t)buflen);8687/* if heap exhausted resort to stack buffer */88if (bufP == NULL) {89bufP = BUF;90buflen = MAX_BUFFER_LEN;91}92}9394while(len > 0) {95int loff = 0;96int chunkLen = min(buflen, len);97int llen = chunkLen;98(*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP);99100if ((*env)->ExceptionCheck(env)) {101break;102} else {103while(llen > 0) {104int n = NET_Send(fd, bufP + loff, llen, 0);105if (n > 0) {106llen -= n;107loff += n;108continue;109}110JNU_ThrowByNameWithMessageAndLastError111(env, "java/net/SocketException", "Write failed");112if (bufP != BUF) {113free(bufP);114}115return;116}117len -= chunkLen;118off += chunkLen;119}120}121122if (bufP != BUF) {123free(bufP);124}125}126127128