--- a/jdk/src/solaris/native/sun/nio/ch/SctpChannelImpl.c Fri Feb 17 10:18:50 2012 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,594 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "Sctp.h"
-
-#include "jni.h"
-#include "nio_util.h"
-#include "nio.h"
-#include "net_util.h"
-#include "net_util_md.h"
-#include "sun_nio_ch_SctpNet.h"
-#include "sun_nio_ch_SctpChannelImpl.h"
-#include "sun_nio_ch_SctpAssocChange.h"
-#include "sun_nio_ch_SctpResultContainer.h"
-#include "sun_nio_ch_SctpPeerAddrChange.h"
-
-/* sizeof(union sctp_notification */
-#define NOTIFICATION_BUFFER_SIZE 280
-
-#define MESSAGE_IMPL_CLASS "sun/nio/ch/SctpMessageInfoImpl"
-#define RESULT_CONTAINER_CLASS "sun/nio/ch/SctpResultContainer"
-#define SEND_FAILED_CLASS "sun/nio/ch/SctpSendFailed"
-#define ASSOC_CHANGE_CLASS "sun/nio/ch/SctpAssocChange"
-#define PEER_CHANGE_CLASS "sun/nio/ch/SctpPeerAddrChange"
-#define SHUTDOWN_CLASS "sun/nio/ch/SctpShutdown"
-
-struct controlData {
- int assocId;
- unsigned short streamNumber;
- jboolean unordered;
- unsigned int ppid;
-};
-
-static jclass smi_class; /* sun.nio.ch.SctpMessageInfoImpl */
-static jmethodID smi_ctrID; /* sun.nio.ch.SctpMessageInfoImpl.<init> */
-static jfieldID src_valueID; /* sun.nio.ch.SctpResultContainer.value */
-static jfieldID src_typeID; /* sun.nio.ch.SctpResultContainer.type */
-static jclass ssf_class; /* sun.nio.ch.SctpSendFailed */
-static jmethodID ssf_ctrID; /* sun.nio.ch.SctpSendFailed.<init> */
-static jclass sac_class; /* sun.nio.ch.SctpAssociationChanged */
-static jmethodID sac_ctrID; /* sun.nio.ch.SctpAssociationChanged.<init> */
-static jclass spc_class; /* sun.nio.ch.SctpPeerAddressChanged */
-static jmethodID spc_ctrID; /* sun.nio.ch.SctpPeerAddressChanged.<init> */
-static jclass ss_class; /* sun.nio.ch.SctpShutdown */
-static jmethodID ss_ctrID; /* sun.nio.ch.SctpShutdown.<init> */
-static jfieldID isa_addrID; /* java.net.InetSocketAddress.addr */
-static jfieldID isa_portID; /* java.net.InetSocketAddress.port */
-
-/* defined in SctpNet.c */
-jobject SockAddrToInetSocketAddress(JNIEnv* env, struct sockaddr* addr);
-
-/* use SocketChannelImpl's checkConnect implementation */
-extern jint Java_sun_nio_ch_SocketChannelImpl_checkConnect(JNIEnv* env,
- jobject this, jobject fdo, jboolean block, jboolean ready);
-
-/*
- * Class: sun_nio_ch_SctpChannelImpl
- * Method: initIDs
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_nio_ch_SctpChannelImpl_initIDs
- (JNIEnv *env, jclass klass) {
- jclass cls;
-
- /* SctpMessageInfoImpl */
- cls = (*env)->FindClass(env, MESSAGE_IMPL_CLASS);
- CHECK_NULL(cls);
- smi_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL(smi_class);
- smi_ctrID = (*env)->GetMethodID(env, cls, "<init>",
- "(ILjava/net/SocketAddress;IIZZI)V");
- CHECK_NULL(smi_ctrID);
-
- /* SctpResultContainer */
- cls = (*env)->FindClass(env, RESULT_CONTAINER_CLASS);
- CHECK_NULL(cls);
- src_valueID = (*env)->GetFieldID(env, cls, "value", "Ljava/lang/Object;");
- CHECK_NULL(src_valueID);
- src_typeID = (*env)->GetFieldID(env, cls, "type", "I");
- CHECK_NULL(src_typeID);
-
- /* SctpSendFailed */
- cls = (*env)->FindClass(env, SEND_FAILED_CLASS);
- CHECK_NULL(cls);
- ssf_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL(ssf_class);
- ssf_ctrID = (*env)->GetMethodID(env, cls, "<init>",
- "(ILjava/net/SocketAddress;Ljava/nio/ByteBuffer;II)V");
- CHECK_NULL(ssf_ctrID);
-
- /* SctpAssocChange */
- cls = (*env)->FindClass(env, ASSOC_CHANGE_CLASS);
- CHECK_NULL(cls);
- sac_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL(sac_class);
- sac_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(IIII)V");
- CHECK_NULL(sac_ctrID);
-
- /* SctpPeerAddrChange */
- cls = (*env)->FindClass(env, PEER_CHANGE_CLASS);
- CHECK_NULL(cls);
- spc_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL(spc_class);
- spc_ctrID = (*env)->GetMethodID(env, cls, "<init>",
- "(ILjava/net/SocketAddress;I)V");
- CHECK_NULL(spc_ctrID);
-
- /* sun.nio.ch.SctpShutdown */
- cls = (*env)->FindClass(env, SHUTDOWN_CLASS);
- CHECK_NULL(cls);
- ss_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL(ss_class);
- ss_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
- CHECK_NULL(ss_ctrID);
-
- /* InetSocketAddress */
- cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
- CHECK_NULL(cls);
- isa_addrID = (*env)->GetFieldID(env, cls, "addr", "Ljava/net/InetAddress;");
- CHECK_NULL(isa_addrID);
- isa_portID = (*env)->GetFieldID(env, cls, "port", "I");
-}
-
-void getControlData
- (struct msghdr* msg, struct controlData* cdata) {
- struct cmsghdr* cmsg;
-
- for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
- if (cmsg->cmsg_level == IPPROTO_SCTP && cmsg->cmsg_type == SCTP_SNDRCV) {
- struct sctp_sndrcvinfo *sri;
-
- sri = (struct sctp_sndrcvinfo *) CMSG_DATA(cmsg);
- cdata->assocId = sri->sinfo_assoc_id;
- cdata->streamNumber = sri->sinfo_stream;
- cdata->unordered = (sri->sinfo_flags & SCTP_UNORDERED) ? JNI_TRUE :
- JNI_FALSE;
- cdata->ppid = ntohl(sri->sinfo_ppid);
-
- return;
- }
- }
- return;
-}
-
-void setControlData
- (struct msghdr* msg, struct controlData* cdata) {
- struct cmsghdr* cmsg;
- struct sctp_sndrcvinfo *sri;
-
- cmsg = CMSG_FIRSTHDR(msg);
- cmsg->cmsg_level = IPPROTO_SCTP;
- cmsg->cmsg_type = SCTP_SNDRCV;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
-
- /* Initialize the payload */
- sri = (struct sctp_sndrcvinfo*) CMSG_DATA(cmsg);
- memset(sri, 0, sizeof (*sri));
-
- if (cdata->streamNumber > 0) {
- sri->sinfo_stream = cdata->streamNumber;
- }
- if (cdata->assocId > 0) {
- sri->sinfo_assoc_id = cdata->assocId;
- }
- if (cdata->unordered == JNI_TRUE) {
- sri->sinfo_flags = sri->sinfo_flags | SCTP_UNORDERED;
- }
-
- if (cdata->ppid > 0) {
- sri->sinfo_ppid = htonl(cdata->ppid);
- }
-
- /* Sum of the length of all control messages in the buffer. */
- msg->msg_controllen = cmsg->cmsg_len;
-}
-
-// TODO: test: can create send failed without any data? if so need to
-// update API so that buffer can be null if no data.
-void handleSendFailed
- (JNIEnv* env, int fd, jobject resultContainerObj, struct sctp_send_failed *ssf,
- int read, jboolean isEOR, struct sockaddr* sap) {
- jobject bufferObj = NULL, resultObj, isaObj;
- char *addressP;
- struct sctp_sndrcvinfo *sri;
- int remaining, dataLength;
-
- /* the actual undelivered message data is directly after the ssf */
- int dataOffset = sizeof(struct sctp_send_failed);
-
- sri = (struct sctp_sndrcvinfo*) &ssf->ssf_info;
-
- /* the number of bytes remaining to be read in the sctp_send_failed notif*/
- remaining = ssf->ssf_length - read;
-
- /* the size of the actual undelivered message */
- dataLength = ssf->ssf_length - dataOffset;
-
- /* retrieved address from sockaddr */
- isaObj = SockAddrToInetSocketAddress(env, sap);
-
- /* data retrieved from sff_data */
- if (dataLength > 0) {
- struct iovec iov[1];
- struct msghdr msg[1];
- int rv, alreadyRead;
- char *dataP = (char*) ssf;
- dataP += dataOffset;
-
- if ((addressP = malloc(dataLength)) == NULL) {
- JNU_ThrowOutOfMemoryError(env, "handleSendFailed");
- return;
- }
-
- memset(msg, 0, sizeof (*msg));
- msg->msg_iov = iov;
- msg->msg_iovlen = 1;
-
- bufferObj = (*env)->NewDirectByteBuffer(env, addressP, dataLength);
- CHECK_NULL(bufferObj);
-
- alreadyRead = read - dataOffset;
- if (alreadyRead > 0) {
- memcpy(addressP, /*ssf->ssf_data*/ dataP, alreadyRead);
- iov->iov_base = addressP + alreadyRead;
- iov->iov_len = dataLength - alreadyRead;
- } else {
- iov->iov_base = addressP;
- iov->iov_len = dataLength;
- }
-
- if (remaining > 0) {
- if ((rv = recvmsg(fd, msg, 0)) < 0) {
- handleSocketError(env, errno);
- return;
- }
-
- if (rv != (dataLength - alreadyRead) || !(msg->msg_flags & MSG_EOR)) {
- //TODO: assert false: "should not reach here";
- return;
- }
- // TODO: Set and document (in API) buffers position.
- }
- }
-
- /* create SctpSendFailed */
- resultObj = (*env)->NewObject(env, ssf_class, ssf_ctrID, ssf->ssf_assoc_id,
- isaObj, bufferObj, ssf->ssf_error, sri->sinfo_stream);
- CHECK_NULL(resultObj);
- (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
- (*env)->SetIntField(env, resultContainerObj, src_typeID,
- sun_nio_ch_SctpResultContainer_SEND_FAILED);
-}
-
-void handleAssocChange
- (JNIEnv* env, jobject resultContainerObj, struct sctp_assoc_change *sac) {
- jobject resultObj;
- int state = 0;
-
- switch (sac->sac_state) {
- case SCTP_COMM_UP :
- state = sun_nio_ch_SctpAssocChange_SCTP_COMM_UP;
- break;
- case SCTP_COMM_LOST :
- state = sun_nio_ch_SctpAssocChange_SCTP_COMM_LOST;
- break;
- case SCTP_RESTART :
- state = sun_nio_ch_SctpAssocChange_SCTP_RESTART;
- break;
- case SCTP_SHUTDOWN_COMP :
- state = sun_nio_ch_SctpAssocChange_SCTP_SHUTDOWN;
- break;
- case SCTP_CANT_STR_ASSOC :
- state = sun_nio_ch_SctpAssocChange_SCTP_CANT_START;
- }
-
- /* create SctpAssociationChanged */
- resultObj = (*env)->NewObject(env, sac_class, sac_ctrID, sac->sac_assoc_id,
- state, sac->sac_outbound_streams, sac->sac_inbound_streams);
- CHECK_NULL(resultObj);
- (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
- (*env)->SetIntField(env, resultContainerObj, src_typeID,
- sun_nio_ch_SctpResultContainer_ASSOCIATION_CHANGED);
-}
-
-void handleShutdown
- (JNIEnv* env, jobject resultContainerObj, struct sctp_shutdown_event* sse) {
- /* create SctpShutdown */
- jobject resultObj = (*env)->NewObject(env, ss_class, ss_ctrID, sse->sse_assoc_id);
- CHECK_NULL(resultObj);
- (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
- (*env)->SetIntField(env, resultContainerObj, src_typeID,
- sun_nio_ch_SctpResultContainer_SHUTDOWN);
-}
-
-void handlePeerAddrChange
- (JNIEnv* env, jobject resultContainerObj, struct sctp_paddr_change* spc) {
- int event = 0;
- jobject addressObj, resultObj;
- unsigned int state = spc->spc_state;
-
- switch (state) {
- case SCTP_ADDR_AVAILABLE :
- event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_AVAILABLE;
- break;
- case SCTP_ADDR_UNREACHABLE :
- event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_UNREACHABLE;
- break;
- case SCTP_ADDR_REMOVED :
- event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_REMOVED;
- break;
- case SCTP_ADDR_ADDED :
- event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_ADDED;
- break;
- case SCTP_ADDR_MADE_PRIM :
- event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_MADE_PRIM;
-#ifdef __linux__ /* Solaris currently doesn't support SCTP_ADDR_CONFIRMED */
- break;
- case SCTP_ADDR_CONFIRMED :
- event = sun_nio_ch_SctpPeerAddrChange_SCTP_ADDR_CONFIRMED;
-#endif /* __linux__ */
- }
-
- addressObj = SockAddrToInetSocketAddress(env, (struct sockaddr*)&spc->spc_aaddr);
-
- /* create SctpPeerAddressChanged */
- resultObj = (*env)->NewObject(env, spc_class, spc_ctrID, spc->spc_assoc_id,
- addressObj, event);
- CHECK_NULL(resultObj);
- (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
- (*env)->SetIntField(env, resultContainerObj, src_typeID,
- sun_nio_ch_SctpResultContainer_PEER_ADDRESS_CHANGED);
-}
-
-void handleUninteresting
- (union sctp_notification *snp) {
- //fprintf(stdout,"\nNative: handleUninterestingNotification: Receive notification type [%u]", snp->sn_header.sn_type);
-}
-
-/**
- * Handle notifications from the SCTP stack.
- * Returns JNI_TRUE if the notification is one that is of interest to the
- * Java API, otherwise JNI_FALSE.
- */
-jboolean handleNotification
- (JNIEnv* env, int fd, jobject resultContainerObj, union sctp_notification* snp,
- int read, jboolean isEOR, struct sockaddr* sap) {
- switch (snp->sn_header.sn_type) {
- case SCTP_SEND_FAILED:
- handleSendFailed(env, fd, resultContainerObj, &snp->sn_send_failed,
- read, isEOR, sap);
- return JNI_TRUE;
- case SCTP_ASSOC_CHANGE:
- handleAssocChange(env, resultContainerObj, &snp->sn_assoc_change);
- return JNI_TRUE;
- case SCTP_SHUTDOWN_EVENT:
- handleShutdown(env, resultContainerObj, &snp->sn_shutdown_event);
- return JNI_TRUE;
- case SCTP_PEER_ADDR_CHANGE:
- handlePeerAddrChange(env, resultContainerObj, &snp->sn_paddr_change);
- return JNI_TRUE;
- default :
- /* the Java API is not interested in this event, maybe we are? */
- handleUninteresting(snp);
- }
- return JNI_FALSE;
-}
-
-void handleMessage
- (JNIEnv* env, jobject resultContainerObj, struct msghdr* msg,int read,
- jboolean isEOR, struct sockaddr* sap) {
- jobject isa, resultObj;
- struct controlData cdata[1];
-
- if (read == 0) {
- /* we reached EOF */
- read = -1;
- }
-
- isa = SockAddrToInetSocketAddress(env, sap);
- getControlData(msg, cdata);
-
- /* create SctpMessageInfoImpl */
- resultObj = (*env)->NewObject(env, smi_class, smi_ctrID, cdata->assocId,
- isa, read, cdata->streamNumber,
- isEOR ? JNI_TRUE : JNI_FALSE,
- cdata->unordered, cdata->ppid);
- CHECK_NULL(resultObj);
- (*env)->SetObjectField(env, resultContainerObj, src_valueID, resultObj);
- (*env)->SetIntField(env, resultContainerObj, src_typeID,
- sun_nio_ch_SctpResultContainer_MESSAGE);
-}
-
-/*
- * Class: sun_nio_ch_SctpChannelImpl
- * Method: receive0
- * Signature: (ILsun/nio/ch/SctpResultContainer;JIZ)I
- */
-JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_receive0
- (JNIEnv *env, jclass klass, jint fd, jobject resultContainerObj,
- jlong address, jint length, jboolean peek) {
- SOCKADDR sa;
- int sa_len = sizeof(sa);
- ssize_t rv = 0;
- jlong *addr = jlong_to_ptr(address);
- struct iovec iov[1];
- struct msghdr msg[1];
- char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
- int flags = peek == JNI_TRUE ? MSG_PEEK : 0;
-
- /* Set up the msghdr structure for receiving */
- memset(msg, 0, sizeof (*msg));
- msg->msg_name = &sa;
- msg->msg_namelen = sa_len;
- iov->iov_base = addr;
- iov->iov_len = length;
- msg->msg_iov = iov;
- msg->msg_iovlen = 1;
- msg->msg_control = cbuf;
- msg->msg_controllen = sizeof(cbuf);
- msg->msg_flags = 0;
-
- do {
- if ((rv = recvmsg(fd, msg, flags)) < 0) {
- if (errno == EWOULDBLOCK) {
- return IOS_UNAVAILABLE;
- } else if (errno == EINTR) {
- return IOS_INTERRUPTED;
-
-#ifdef __linux__
- } else if (errno == ENOTCONN) {
- /* ENOTCONN when EOF reached */
- rv = 0;
- /* there will be no control data */
- msg->msg_controllen = 0;
-#endif /* __linux__ */
-
- } else {
- handleSocketError(env, errno);
- return 0;
- }
- }
-
- if (msg->msg_flags & MSG_NOTIFICATION) {
- char *bufp = (char*)addr;
- union sctp_notification *snp;
-
- if (!(msg->msg_flags & MSG_EOR) && length < NOTIFICATION_BUFFER_SIZE) {
- char buf[NOTIFICATION_BUFFER_SIZE];
- int rvSAVE = rv;
- memcpy(buf, addr, rv);
- iov->iov_base = buf + rv;
- iov->iov_len = NOTIFICATION_BUFFER_SIZE - rv;
- if ((rv = recvmsg(fd, msg, flags)) < 0) {
- handleSocketError(env, errno);
- return 0;
- }
- bufp = buf;
- rv += rvSAVE;
- }
- snp = (union sctp_notification *) bufp;
- if (handleNotification(env, fd, resultContainerObj, snp, rv,
- (msg->msg_flags & MSG_EOR),
- (struct sockaddr*)&sa ) == JNI_TRUE) {
- /* We have received a notification that is of interest to
- to the Java API. The appropriate notification will be
- set in the result container. */
- return 0;
- }
-
- // set iov back to addr, and reset msg_controllen
- iov->iov_base = addr;
- iov->iov_len = length;
- msg->msg_control = cbuf;
- msg->msg_controllen = sizeof(cbuf);
- }
- } while (msg->msg_flags & MSG_NOTIFICATION);
-
- handleMessage(env, resultContainerObj, msg, rv,
- (msg->msg_flags & MSG_EOR), (struct sockaddr*)&sa);
- return rv;
-}
-
-/*
- * Class: sun_nio_ch_SctpChannelImpl
- * Method: send0
- * Signature: (IJILjava/net/SocketAddress;IIZI)I
- */
-JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_send0
- (JNIEnv *env, jclass klass, jint fd, jlong address, jint length,
- jobject saTarget, jint assocId, jint streamNumber, jboolean unordered,
- jint ppid) {
- SOCKADDR sa;
- int sa_len = sizeof(sa);
- ssize_t rv = 0;
- jlong *addr = jlong_to_ptr(address);
- struct iovec iov[1];
- struct msghdr msg[1];
- int cbuf_size = CMSG_SPACE(sizeof (struct sctp_sndrcvinfo));
- char cbuf[CMSG_SPACE(sizeof (struct sctp_sndrcvinfo))];
- struct controlData cdata[1];
-
- /* SctpChannel:
- * saTarget may contain the preferred address or NULL to use primary,
- * assocId will always be -1
- * SctpMultiChannell:
- * Setup new association, saTarget will contain address, assocId = -1
- * Association already existing, assocId != -1, saTarget = preferred addr
- */
- if (saTarget != NULL /*&& assocId <= 0*/) {
-
- jobject targetAddress = (*env)->GetObjectField(env, saTarget, isa_addrID);
- jint targetPort = (*env)->GetIntField(env, saTarget, isa_portID);
-
- if (NET_InetAddressToSockaddr(env, targetAddress, targetPort,
- (struct sockaddr *)&sa,
- &sa_len, JNI_TRUE) != 0) {
- return IOS_THROWN;
- }
- } else {
- memset(&sa, '\x0', sa_len);
- sa_len = 0;
- }
-
- /* Set up the msghdr structure for sending */
- memset(msg, 0, sizeof (*msg));
- memset(cbuf, 0, cbuf_size);
- msg->msg_name = &sa;
- msg->msg_namelen = sa_len;
- iov->iov_base = addr;
- iov->iov_len = length;
- msg->msg_iov = iov;
- msg->msg_iovlen = 1;
- msg->msg_control = cbuf;
- msg->msg_controllen = cbuf_size;
- msg->msg_flags = 0;
-
- cdata->streamNumber = streamNumber;
- cdata->assocId = assocId;
- cdata->unordered = unordered;
- cdata->ppid = ppid;
- setControlData(msg, cdata);
-
- if ((rv = sendmsg(fd, msg, 0)) < 0) {
- if (errno == EWOULDBLOCK) {
- return IOS_UNAVAILABLE;
- } else if (errno == EINTR) {
- return IOS_INTERRUPTED;
- } else if (errno == EPIPE) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "Socket is shutdown for writing");
- } else {
- handleSocketError(env, errno);
- return 0;
- }
- }
-
- return rv;
-}
-
-/*
- * Class: sun_nio_ch_SctpChannelImpl
- * Method: checkConnect
- * Signature: (Ljava/io/FileDescriptor;ZZ)I
- */
-JNIEXPORT jint JNICALL Java_sun_nio_ch_SctpChannelImpl_checkConnect
- (JNIEnv* env, jobject this, jobject fdo, jboolean block, jboolean ready) {
- return Java_sun_nio_ch_SocketChannelImpl_checkConnect(env, this,
- fdo, block, ready);
-}
-