annotate src/java.base/unix/native/libnet/SocketOutputStream.c @ 51029:43b54a307c89

8203937: Not possible to read data from socket after write detects connection reset Reviewed-by: chegar
author alanb
date Wed, 06 Jun 2018 12:17:01 +0100
parents 71c04702a3d5
children
rev   line source
duke@2 1 /*
clanger@39318 2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
duke@2 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@2 4 *
duke@2 5 * This code is free software; you can redistribute it and/or modify it
duke@2 6 * under the terms of the GNU General Public License version 2 only, as
ohair@5506 7 * published by the Free Software Foundation. Oracle designates this
duke@2 8 * particular file as subject to the "Classpath" exception as provided
ohair@5506 9 * by Oracle in the LICENSE file that accompanied this code.
duke@2 10 *
duke@2 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@2 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@2 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@2 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@2 15 * accompanied this code).
duke@2 16 *
duke@2 17 * You should have received a copy of the GNU General Public License version
duke@2 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@2 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@2 20 *
ohair@5506 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@5506 22 * or visit www.oracle.com if you need additional information or have any
ohair@5506 23 * questions.
duke@2 24 */
clanger@41771 25 #include <errno.h>
clanger@41771 26 #include <stdlib.h>
clanger@41771 27 #include <string.h>
duke@2 28
duke@2 29 #include "net_util.h"
duke@2 30
duke@2 31 #include "java_net_SocketOutputStream.h"
duke@2 32
duke@2 33 #define min(a, b) ((a) < (b) ? (a) : (b))
duke@2 34
duke@2 35 /*
duke@2 36 * SocketOutputStream
duke@2 37 */
duke@2 38
duke@2 39 static jfieldID IO_fd_fdID;
duke@2 40
duke@2 41 /*
duke@2 42 * Class: java_net_SocketOutputStream
duke@2 43 * Method: init
duke@2 44 * Signature: ()V
duke@2 45 */
duke@2 46 JNIEXPORT void JNICALL
duke@2 47 Java_java_net_SocketOutputStream_init(JNIEnv *env, jclass cls) {
duke@2 48 IO_fd_fdID = NET_GetFileDescriptorID(env);
duke@2 49 }
duke@2 50
duke@2 51 /*
duke@2 52 * Class: java_net_SocketOutputStream
duke@2 53 * Method: socketWrite0
duke@2 54 * Signature: (Ljava/io/FileDescriptor;[BII)V
duke@2 55 */
duke@2 56 JNIEXPORT void JNICALL
duke@2 57 Java_java_net_SocketOutputStream_socketWrite0(JNIEnv *env, jobject this,
duke@2 58 jobject fdObj,
duke@2 59 jbyteArray data,
duke@2 60 jint off, jint len) {
duke@2 61 char *bufP;
duke@2 62 char BUF[MAX_BUFFER_LEN];
duke@2 63 int buflen;
duke@2 64 int fd;
duke@2 65
duke@2 66 if (IS_NULL(fdObj)) {
duke@2 67 JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
duke@2 68 return;
duke@2 69 } else {
duke@2 70 fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
duke@2 71 /* Bug 4086704 - If the Socket associated with this file descriptor
martin@28059 72 * was closed (sysCloseFD), the file descriptor is set to -1.
duke@2 73 */
duke@2 74 if (fd == -1) {
duke@2 75 JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
duke@2 76 return;
duke@2 77 }
duke@2 78
duke@2 79 }
duke@2 80
duke@2 81 if (len <= MAX_BUFFER_LEN) {
duke@2 82 bufP = BUF;
duke@2 83 buflen = MAX_BUFFER_LEN;
duke@2 84 } else {
duke@2 85 buflen = min(MAX_HEAP_BUFFER_LEN, len);
duke@2 86 bufP = (char *)malloc((size_t)buflen);
duke@2 87
duke@2 88 /* if heap exhausted resort to stack buffer */
duke@2 89 if (bufP == NULL) {
duke@2 90 bufP = BUF;
duke@2 91 buflen = MAX_BUFFER_LEN;
duke@2 92 }
duke@2 93 }
duke@2 94
duke@2 95 while(len > 0) {
duke@2 96 int loff = 0;
duke@2 97 int chunkLen = min(buflen, len);
duke@2 98 int llen = chunkLen;
duke@2 99 (*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP);
duke@2 100
msheppar@43202 101 if ((*env)->ExceptionCheck(env)) {
msheppar@43202 102 break;
msheppar@43202 103 } else {
msheppar@43202 104 while(llen > 0) {
msheppar@43202 105 int n = NET_Send(fd, bufP + loff, llen, 0);
msheppar@43202 106 if (n > 0) {
msheppar@43202 107 llen -= n;
msheppar@43202 108 loff += n;
msheppar@43202 109 continue;
msheppar@43202 110 }
alanb@51029 111 JNU_ThrowByNameWithMessageAndLastError
alanb@51029 112 (env, "java/net/SocketException", "Write failed");
msheppar@43202 113 if (bufP != BUF) {
msheppar@43202 114 free(bufP);
msheppar@43202 115 }
msheppar@43202 116 return;
duke@2 117 }
msheppar@43202 118 len -= chunkLen;
msheppar@43202 119 off += chunkLen;
duke@2 120 }
duke@2 121 }
duke@2 122
duke@2 123 if (bufP != BUF) {
duke@2 124 free(bufP);
duke@2 125 }
duke@2 126 }